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

Flutter自定义Slider开发需求:实现如图所示的滑块样式

Flutter实现自定义样式Slider

要实现你需要的自定义Slider样式,核心是通过Flutter的SliderTheme配合自定义的滑块形状(SliderComponentShape)和轨道形状(SliderTrackShape)来实现,以下是完整的实现方案:

1. 自定义滑块样式

创建自定义的滑块形状类,实现实心圆+白色边框的滑块效果:

class CustomSliderThumbShape extends SliderComponentShape {
  final double thumbRadius;

  const CustomSliderThumbShape({this.thumbRadius = 10.0});

  @override
  Size getPreferredSize(bool isEnabled, bool isDiscrete) {
    return Size.fromRadius(thumbRadius);
  }

  @override
  void paint(
    PaintingContext context,
    Offset center, {
    required Animation<double> activationAnimation,
    required Animation<double> enableAnimation,
    required bool isDiscrete,
    required TextPainter labelPainter,
    required RenderBox parentBox,
    required SliderThemeData sliderTheme,
    required TextDirection textDirection,
    required double value,
    required double textScaleFactor,
    required Size sizeWithOverflow,
  }) {
    final canvas = context.canvas;
    
    // 绘制实心滑块主体
    final fillPaint = Paint()
      ..color = Colors.blue
      ..style = PaintingStyle.fill;
    canvas.drawCircle(center, thumbRadius, fillPaint);

    // 绘制滑块白色边框
    final borderPaint = Paint()
      ..color = Colors.white
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2.0;
    canvas.drawCircle(center, thumbRadius, borderPaint);
  }
}

2. 自定义轨道样式

创建带渐变效果的轨道形状,区分激活和未激活区域:

class CustomSliderTrackShape extends RoundedRectSliderTrackShape {
  @override
  void paint(
    PaintingContext context,
    Offset offset, {
    required RenderBox parentBox,
    required SliderThemeData sliderTheme,
    required Animation<double> enableAnimation,
    required TextDirection textDirection,
    required Offset thumbCenter,
    bool isDiscrete = false,
    bool isEnabled = false,
    double additionalActiveTrackHeight = 2,
  }) {
    if (sliderTheme.trackHeight == null || sliderTheme.trackHeight! <= 0) return;

    final canvas = context.canvas;
    final trackHeight = sliderTheme.trackHeight!;
    final trackRect = Rect.fromLTWH(
      offset.dx,
      offset.dy + (parentBox.size.height - trackHeight) / 2,
      parentBox.size.width,
      trackHeight,
    );

    // 绘制未激活轨道(灰色背景)
    final inactivePaint = Paint()
      ..color = Colors.grey.shade300
      ..style = PaintingStyle.fill;
    canvas.drawRRect(
      RRect.fromRectAndRadius(trackRect, Radius.circular(trackHeight / 2)),
      inactivePaint,
    );

    // 绘制激活轨道(蓝色渐变)
    final activeTrackRect = Rect.fromLTWH(
      trackRect.left,
      trackRect.top,
      thumbCenter.dx - trackRect.left,
      trackRect.height,
    );
    final activePaint = Paint()
      ..shader = LinearGradient(
        colors: [Colors.blue.shade400, Colors.blue.shade600],
        begin: Alignment.centerLeft,
        end: Alignment.centerRight,
      ).createShader(activeTrackRect);
    canvas.drawRRect(
      RRect.fromRectAndRadius(activeTrackRect, Radius.circular(trackHeight / 2)),
      activePaint,
    );
  }
}

3. 使用自定义Slider

通过SliderTheme包裹原生Slider,应用自定义样式:

double _currentValue = 0.5;

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Center(
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 32.0),
        child: SliderTheme(
          data: SliderTheme.of(context).copyWith(
            trackHeight: 8.0, // 轨道高度
            thumbShape: const CustomSliderThumbShape(thumbRadius: 12.0), // 滑块大小
            trackShape: const CustomSliderTrackShape(), // 自定义轨道
            overlayColor: Colors.blue.withOpacity(0.2), // 滑块点击反馈颜色
            overlayShape: const RoundSliderOverlayShape(overlayRadius: 20.0), // 反馈区域大小
          ),
          child: Slider(
            value: _currentValue,
            min: 0,
            max: 1,
            onChanged: (value) {
              setState(() => _currentValue = value);
            },
          ),
        ),
      ),
    ),
  );
}

额外扩展

  • 如果需要添加刻度标记,可以在Slider上下方添加Row组件,根据min、max和divisions参数生成对应的刻度文本或线条。
  • 可根据需求修改滑块颜色、轨道渐变色、尺寸等参数,适配不同设计风格。
  • 若需离散型Slider,只需给Slider添加divisions参数即可,自定义形状无需额外修改。

内容的提问来源于stack exchange,提问作者Shekhar J. Lobo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 19:10:32