当前位置:   article > 正文

Flutter Slider自定义滑块样式 Slider的label标签框常显示

Flutter Slider自定义滑块样式 Slider的label标签框常显示

1、自定义Slider滑块样式

Flutter Slider控件的滑块系统样式是一个圆点,thumbShape默认样式是RoundSliderThumbShape,如果想要使用其它的样式就需要自定义一下thumbShape;

例如需要一个上图样式的(圆点+半透明圆形边框)的滑块

  1. class CustomSliderThumbShape extends SliderComponentShape {
  2. final Size size = const Size(40, 40);
  3. @override
  4. Size getPreferredSize(bool isEnabled, bool isDiscrete) {
  5. return size;
  6. }
  7. @override
  8. 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}) {
  9. final Canvas canvas = context.canvas;
  10. final Paint paint = Paint();
  11. paint.color = const Color(0XFFEF5133);
  12. paint.isAntiAlias = true;
  13. final Paint paint2 = Paint();
  14. paint2.color = const Color(0x30EF5133);
  15. paint2.isAntiAlias = true;
  16. //绘制滑块
  17. canvas.drawCircle(center, 5, paint);
  18. canvas.drawCircle(center, 14, paint2);
  19. }
  20. }

然后再使用 SliderThemeData控件的 thumbShape属性设置一下就行了;

  1. SliderTheme(
  2. data: SliderThemeData(
  3. thumbShape: CustomSliderThumbShape(),
  4. ),
  5. child: Slider(
  6. ),
  7. ),

2、Slider的label标签框常显示

上图,Slider的label标签只有按住滑动块时才会显示,松开手指后label标签就会消失,设置 showValueIndicator: ShowValueIndicator.always,也不能一直显示;

若要Slider的label标签框常显示,可以把label标签框和滑块写在一起,使用SliderComponentShape自定义一下布局;

  1. class IndicatorSliderThumbShape extends SliderComponentShape {
  2. IndicatorSliderThumbShape(this.msg);
  3. String msg;
  4. @override
  5. Size getPreferredSize(bool isEnabled, bool isDiscrete) {
  6. return const Size(15, 40);
  7. }
  8. TextPainter labelTextPainter = TextPainter()
  9. ..textDirection = TextDirection.ltr;
  10. @override
  11. 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}) {
  12. final Canvas canvas = context.canvas;
  13. final Paint paint = Paint();
  14. paint.color = const Color(0XFFEF5133);
  15. paint.isAntiAlias = true;
  16. //绘制圆点滑块
  17. canvas.drawCircle(center, 4, paint);
  18. final Paint paint2 = Paint();
  19. paint2.color = const Color(0X30EF5133);
  20. paint2.isAntiAlias = true;
  21. //绘制半透明滑块
  22. canvas.drawCircle(center, 12, paint2);
  23. //在thumb上面添加一个自定义labels
  24. //绘制labels的圆角矩形
  25. final Paint paint3 = Paint();
  26. paint3.color = const Color(0xFF2C28E8);
  27. paint3.isAntiAlias = true;
  28. var rr = RRect.fromLTRBXY(center.dx+30, center.dy-20, center.dx-30, center.dy-50 , 8,8);
  29. canvas.drawRRect(rr, paint3);
  30. //绘制labels的三角形指示块
  31. final Paint paint4 = Paint();
  32. paint4.color = const Color(0xFF28CD41);
  33. paint4.isAntiAlias = true;
  34. final path = Path();
  35. path.moveTo(center.dx, center.dy-10,);
  36. path.lineTo(center.dx-10, center.dy-20);
  37. path.lineTo(center.dx+10, center.dy-20,);
  38. path.close();
  39. canvas.drawPath(path, paint4);
  40. //绘制labels的文字内容
  41. labelTextPainter.text = TextSpan(
  42. text: msg,
  43. style: const TextStyle(fontSize: 14, color: Colors.white));
  44. labelTextPainter.layout();
  45. labelTextPainter.paint(
  46. canvas,
  47. center.translate(-labelTextPainter.width / 2, -43));
  48. }
  49. }

label框的文字、指示器箭头、圆角背景框都可以自定义;

同样shape设置一下就可以了:

  1. SliderTheme(
  2. data: SliderThemeData(
  3. thumbShape: IndicatorSliderThumbShape('xx-km'),
  4. ),
  5. child: Slider(
  6. ),
  7. ),

下面是Slider的全部代码:

  1. class TestSliderPage extends StatefulWidget {
  2. const TestSliderPage({Key? key}) : super(key: key);
  3. @override
  4. State<TestSliderPage> createState() => _TestSliderPageState();
  5. }
  6. class _TestSliderPageState extends State<TestSliderPage> {
  7. double _sliderValue = 0;
  8. final List<int> _slideValues = [1,3,5,10,20,30,40,50,60,70,80,90,100];
  9. @override
  10. Widget build(BuildContext context) {
  11. return BaseTopView(title: "Slider",
  12. body:
  13. Container(
  14. color: color_fff,
  15. child: SliderTheme(
  16. data: SliderThemeData(
  17. thumbShape: IndicatorSliderThumbShape('${_slideValues[_sliderValue.toInt()]}km'),
  18. trackHeight: ScreenUtils.getDip(1.5),
  19. thumbColor: color_EF5133,
  20. //滑块颜色
  21. activeTrackColor: color_EF5133,
  22. //已选中颜色
  23. inactiveTrackColor: color_EF5133.withAlpha(15),
  24. //未选中颜色
  25. activeTickMarkColor: Colors.transparent,
  26. //指示器点颜色
  27. inactiveTickMarkColor: Colors.transparent,
  28. //指示器点颜色
  29. valueIndicatorColor: color_EF5133,
  30. //气泡颜色
  31. overlayColor: color_EF5133.withAlpha(15),
  32. showValueIndicator: ShowValueIndicator.never,
  33. valueIndicatorTextStyle: TextStyle(fontSize: 11),
  34. ),
  35. child: Slider(
  36. value: _sliderValue,
  37. min: 0,
  38. max: 12,
  39. onChanged: (newValue) {
  40. setState(() {
  41. _sliderValue = newValue;
  42. });
  43. },
  44. label: '${_slideValues[_sliderValue.toInt()]}km',
  45. divisions: _slideValues.length - 1,
  46. ),
  47. ),
  48. ),);
  49. }
  50. }

随手记录、、、

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号