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

在Flutter中如何创建随数值变化色彩浓度的水平条?

实现思路与代码示例

要实现根据数值改变色彩浓度的水平条,核心是将数值映射为颜色参数(饱和度、透明度等),再结合Flutter的布局或绘制组件落地,下面给两种实用方案:

方案一:用Container快速实现(适合简单场景)

通过计算输入数值的比例,动态调整颜色的饱和度或透明度,用嵌套Container实现进度条:

class ColorProgressBar extends StatelessWidget {
  final double value; // 传入的数值,比如0-100
  final double maxValue; // 数值的最大值,默认100
  final Color baseColor; // 基础颜色

  const ColorProgressBar({
    super.key,
    required this.value,
    this.maxValue = 100,
    this.baseColor = Colors.blue,
  });

  @override
  Widget build(BuildContext context) {
    // 把数值转成0-1的比例,防止超出范围
    final double ratio = (value / maxValue).clamp(0.0, 1.0);
    
    // 调整色彩饱和度(更贴合"色彩浓度"的视觉需求)
    final hsl = HSLColor.fromColor(baseColor);
    final Color dynamicColor = hsl.withSaturation(ratio).toColor();

    // 也可以选择调整透明度实现浓度变化
    // final Color dynamicColor = baseColor.withOpacity(ratio);

    return Container(
      height: 20,
      width: double.infinity,
      margin: const EdgeInsets.symmetric(horizontal: 20),
      decoration: BoxDecoration(
        color: Colors.grey.shade200,
        borderRadius: BorderRadius.circular(10),
      ),
      child: Align(
        alignment: Alignment.centerLeft,
        child: Container(
          width: ratio * (MediaQuery.of(context).size.width - 40),
          height: double.infinity,
          decoration: BoxDecoration(
            color: dynamicColor,
            borderRadius: BorderRadius.circular(10),
          ),
        ),
      ),
    );
  }
}

调用示例

// 传入数值70,显示70%浓度的进度条
ColorProgressBar(value: 70)

方案二:用CustomPaint自定义绘制(适合复杂需求)

如果需要更灵活的样式(比如精细的圆角控制、自定义过渡效果),可以用CustomPaint手动绘制:

class CustomColorBarPainter extends CustomPainter {
  final double value;
  final double maxValue;
  final Color baseColor;

  CustomColorBarPainter({
    required this.value,
    this.maxValue = 100,
    this.baseColor = Colors.blue,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final ratio = (value / maxValue).clamp(0.0, 1.0);
    
    // 基于饱和度调整色彩浓度
    final hsl = HSLColor.fromColor(baseColor);
    final dynamicColor = hsl.withSaturation(ratio).toColor();

    // 绘制背景灰条
    final bgPaint = Paint()..color = Colors.grey.shade200;
    canvas.drawRRect(
      RRect.fromRectAndRadius(
        Rect.fromLTWH(0, 0, size.width, size.height),
        const Radius.circular(10),
      ),
      bgPaint,
    );

    // 绘制彩色进度条
    final progressPaint = Paint()..color = dynamicColor;
    canvas.drawRRect(
      RRect.fromRectAndRadius(
        Rect.fromLTWH(0, 0, size.width * ratio, size.height),
        const Radius.circular(10),
      ),
      progressPaint,
    );
  }

  @override
  bool shouldRepaint(CustomColorBarPainter oldDelegate) {
    return oldDelegate.value != value;
  }
}

调用示例

CustomPaint(
  size: const Size(double.infinity, 20),
  painter: CustomColorBarPainter(value: 50),
)

关键细节说明

  • 数值映射:必须用clamp(0.0,1.0)限制比例范围,避免数值超出最大值或小于0时出现布局异常;
  • 色彩浓度:优先用HSLColor调整饱和度(saturation),比调整透明度更贴合"色彩浓度"的视觉定义;
  • 响应式适配:进度条宽度可以结合MediaQuery适配不同屏幕,或直接用double.infinity配合父容器的约束。

内容的提问来源于stack exchange,提问作者Macdonald

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 22:27:31