1、自定义Slider滑块样式
Flutter Slider控件的滑块系统样式是一个圆点,thumbShape默认样式是RoundSliderThumbShape,如果想要使用其它的样式就需要自定义一下thumbShape;
例如需要一个上图样式的(圆点+半透明圆形边框)的滑块:
class CustomSliderThumbShape extends SliderComponentShape {
final Size size = const Size(40, 40);
@override
Size getPreferredSize(bool isEnabled, bool isDiscrete) {
return size;
}
@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 canvas = context.canvas;
final Paint paint = Paint();
paint.color = const Color(0XFFEF5133);
paint.isAntiAlias = true;
final Paint paint2 = Paint();
paint2.color = const Color(0x30EF5133);
paint2.isAntiAlias = true;
//绘制滑块
canvas.drawCircle(center, 5, paint);
canvas.drawCircle(center, 14, paint2);
}
}
然后再使用 SliderThemeData控件的 thumbShape属性设置一下就行了;
SliderTheme(
data: SliderThemeData(
thumbShape: CustomSliderThumbShape(),
),
child: Slider(
),
),
2、Slider的label标签框常显示
上图,Slider的label标签只有按住滑动块时才会显示,松开手指后label标签就会消失,设置 showValueIndicator: ShowValueIndicator.always,也不能一直显示;
若要Slider的label标签框常显示,可以把label标签框和滑块写在一起,使用SliderComponentShape自定义一下布局;
class IndicatorSliderThumbShape extends SliderComponentShape {
IndicatorSliderThumbShape(this.msg);
String msg;
@override
Size getPreferredSize(bool isEnabled, bool isDiscrete) {
return const Size(15, 40);
}
TextPainter labelTextPainter = TextPainter()
..textDirection = TextDirection.ltr;
@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 canvas = context.canvas;
final Paint paint = Paint();
paint.color = const Color(0XFFEF5133);
paint.isAntiAlias = true;
//绘制圆点滑块
canvas.drawCircle(center, 4, paint);
final Paint paint2 = Paint();
paint2.color = const Color(0X30EF5133);
paint2.isAntiAlias = true;
//绘制半透明滑块
canvas.drawCircle(center, 12, paint2);
//在thumb上面添加一个自定义labels
//绘制labels的圆角矩形
final Paint paint3 = Paint();
paint3.color = const Color(0xFF2C28E8);
paint3.isAntiAlias = true;
var rr = RRect.fromLTRBXY(center.dx+30, center.dy-20, center.dx-30, center.dy-50 , 8,8);
canvas.drawRRect(rr, paint3);
//绘制labels的三角形指示块
final Paint paint4 = Paint();
paint4.color = const Color(0xFF28CD41);
paint4.isAntiAlias = true;
final path = Path();
path.moveTo(center.dx, center.dy-10,);
path.lineTo(center.dx-10, center.dy-20);
path.lineTo(center.dx+10, center.dy-20,);
path.close();
canvas.drawPath(path, paint4);
//绘制labels的文字内容
labelTextPainter.text = TextSpan(
text: msg,
style: const TextStyle(fontSize: 14, color: Colors.white));
labelTextPainter.layout();
labelTextPainter.paint(
canvas,
center.translate(-labelTextPainter.width / 2, -43));
}
}
label框的文字、指示器箭头、圆角背景框都可以自定义;
同样shape设置一下就可以了:
SliderTheme(
data: SliderThemeData(
thumbShape: IndicatorSliderThumbShape('xx-km'),
),
child: Slider(
),
),
下面是Slider的全部代码:
class TestSliderPage extends StatefulWidget {
const TestSliderPage({Key? key}) : super(key: key);
@override
State<TestSliderPage> createState() => _TestSliderPageState();
}
class _TestSliderPageState extends State<TestSliderPage> {
double _sliderValue = 0;
final List<int> _slideValues = [1,3,5,10,20,30,40,50,60,70,80,90,100];
@override
Widget build(BuildContext context) {
return BaseTopView(title: "Slider",
body:
Container(
color: color_fff,
child: SliderTheme(
data: SliderThemeData(
thumbShape: IndicatorSliderThumbShape('${_slideValues[_sliderValue.toInt()]}km'),
trackHeight: ScreenUtils.getDip(1.5),
thumbColor: color_EF5133,
//滑块颜色
activeTrackColor: color_EF5133,
//已选中颜色
inactiveTrackColor: color_EF5133.withAlpha(15),
//未选中颜色
activeTickMarkColor: Colors.transparent,
//指示器点颜色
inactiveTickMarkColor: Colors.transparent,
//指示器点颜色
valueIndicatorColor: color_EF5133,
//气泡颜色
overlayColor: color_EF5133.withAlpha(15),
showValueIndicator: ShowValueIndicator.never,
valueIndicatorTextStyle: TextStyle(fontSize: 11),
),
child: Slider(
value: _sliderValue,
min: 0,
max: 12,
onChanged: (newValue) {
setState(() {
_sliderValue = newValue;
});
},
label: '${_slideValues[_sliderValue.toInt()]}km',
divisions: _slideValues.length - 1,
),
),
),);
}
}
随手记录、、、