You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter如何实现带标签的多色水平分割线?新手求实现方案

Flutter 带标签多色水平分割线实现方案

方案1:组件组合实现(新手友好,易修改)

不需要复杂的自定义绘制逻辑,直接用Flutter自带组件组合即可实现,后续修改样式也很直观:

import 'package:flutter/material.dart';

class TaggedMultiColorDivider extends StatelessWidget {
  /// 中间显示的标签文本
  final String label;
  /// 分割线高度
  final double dividerHeight;
  /// 标签和左右分割线的间距
  final double labelHorizontalPadding;
  /// 分割线颜色列表,按列表顺序排列分段
  final List<Color> dividerSegmentColors;
  /// 标签文本样式
  final TextStyle? labelStyle;

  const TaggedMultiColorDivider({
    super.key,
    required this.label,
    this.dividerHeight = 2,
    this.labelHorizontalPadding = 12,
    required this.dividerSegmentColors,
    this.labelStyle,
  });

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        // 左侧多色分割线
        Expanded(child: _buildColorSegments()),
        // 中间标签
        Padding(
          padding: EdgeInsets.symmetric(horizontal: labelHorizontalPadding),
          child: Text(
            label,
            style: labelStyle ?? const TextStyle(fontSize: 14, color: Colors.grey),
          ),
        ),
        // 右侧多色分割线
        Expanded(child: _buildColorSegments()),
      ],
    );
  }

  Widget _buildColorSegments() {
    return Row(
      children: dividerSegmentColors.map((color) {
        // 如果需要不等宽分段,把Expanded改成指定宽度的SizedBox即可
        return Expanded(
          child: Container(
            height: dividerHeight,
            color: color,
            // 如需圆角分割线,放开下面的注释配置圆角即可
            // decoration: BoxDecoration(
            //   color: color,
            //   borderRadius: BorderRadius.circular(2),
            // ),
          ),
        );
      }).toList(),
    );
  }
}

// 调用示例,直接放到页面布局的对应位置即可
// TaggedMultiColorDivider(
//   label: "OR",
//   dividerSegmentColors: [Colors.redAccent, Colors.blueAccent, Colors.greenAccent],
// )

方案2:CustomPaint 实现(灵活度更高)

如果需要实现更复杂的效果,比如渐变、斜向分割、特殊形状分段,可以用自定义绘制的方案,性能更好:

import 'package:flutter/material.dart';

class CustomTaggedDivider extends StatelessWidget {
  final String label;
  final double dividerHeight;
  final List<Color> segmentColors;
  final TextStyle? labelStyle;

  const CustomTaggedDivider({
    super.key,
    required this.label,
    required this.segmentColors,
    this.dividerHeight = 2,
    this.labelStyle,
  });

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: _DividerPainter(
        label: label,
        dividerHeight: dividerHeight,
        segmentColors: segmentColors,
        labelStyle: labelStyle ?? const TextStyle(fontSize: 14, color: Colors.grey),
      ),
      child: Container(
        padding: const EdgeInsets.symmetric(vertical: 8),
        alignment: Alignment.center,
        child: Text(label, style: labelStyle),
      ),
    );
  }
}

class _DividerPainter extends CustomPainter {
  final String label;
  final double dividerHeight;
  final List<Color> segmentColors;
  final TextStyle labelStyle;

  _DividerPainter({
    required this.label,
    required this.dividerHeight,
    required this.segmentColors,
    required this.labelStyle,
  });

  @override
  void paint(Canvas canvas, Size size) {
    // 计算文本宽度,预留标签位置
    final textPainter = TextPainter(
      text: TextSpan(text: label, style: labelStyle),
      textDirection: TextDirection.ltr,
    )..layout();
    final textWidth = textPainter.width;
    const gap = 24.0;
    final singleSideDividerWidth = (size.width - textWidth - gap * 2) / 2;
    final singleSegmentWidth = singleSideDividerWidth / segmentColors.length;

    // 绘制左侧分割线
    double offsetX = 0;
    for (var color in segmentColors) {
      final paint = Paint()..color = color;
      canvas.drawRect(
        Rect.fromLTWH(offsetX, size.height/2, singleSegmentWidth, dividerHeight),
        paint,
      );
      offsetX += singleSegmentWidth;
    }

    // 绘制右侧分割线
    offsetX = size.width - singleSideDividerWidth;
    for (var color in segmentColors) {
      final paint = Paint()..color = color;
      canvas.drawRect(
        Rect.fromLTWH(offsetX, size.height/2, singleSegmentWidth, dividerHeight),
        paint,
      );
      offsetX += singleSegmentWidth;
    }
  }

  @override
  bool shouldRepaint(covariant _DividerPainter oldDelegate) {
    return label != oldDelegate.label ||
        dividerHeight != oldDelegate.dividerHeight ||
        segmentColors != oldDelegate.segmentColors ||
        labelStyle != oldDelegate.labelStyle;
  }
}

常用参数调整说明

  • 调整dividerHeight可以修改分割线的粗细
  • 增删dividerSegmentColors/segmentColors列表的元素,可以修改分割线的分段数量和对应颜色
  • 修改label参数即可更换中间显示的标签文本
  • 配置labelStyle可以调整标签的文字大小、颜色、字重等样式

内容的提问来源于stack exchange,提问作者Meng Cheng teoh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 08:45:04