公司项目需要做一个年龄选择器,所以选择RangeSlider,但是RangeSlider有个问题,就是Labels无法一直显示,只有在交互时才显示,就算将SliderTheme中showValueIndicator设置为ShowValueIndicator.never也不行。 暂没找到其他设置办法,于是通过自定义rangeThumbShape间接达成效果,全部源码如下:
import 'package:flutter/material.dart';
void main() {
runApp( MaterialApp(home:const RangerSliderPage() ,));
}
class RangerSliderPage extends StatefulWidget {
const RangerSliderPage({super.key});
@override
State<StatefulWidget> createState() => _RangeSliderPageState();
}
class _RangeSliderPageState extends State<RangerSliderPage>{
late IndicatorRangeSliderThumbShape<int> indicatorRangeSliderThumbShape =
IndicatorRangeSliderThumbShape(18, 60);
late RangeValues rangeValues = const RangeValues(18, 60);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SliderTheme(
data: Theme.of(context)
.sliderTheme
.copyWith(rangeThumbShape: indicatorRangeSliderThumbShape,
showValueIndicator: ShowValueIndicator.never
),
child: RangeSlider(
values: rangeValues,
onChanged: (values) {
indicatorRangeSliderThumbShape.start =
values.start.toInt();
indicatorRangeSliderThumbShape.end = values.end.toInt();
setState(() {
rangeValues=values;
});
},
min: 18,
max: 60,
divisions: 60 - 18,
)),
),
);
}
}
class IndicatorRangeSliderThumbShape<T> extends RangeSliderThumbShape {
IndicatorRangeSliderThumbShape(this.start, this.end);
@override
Size getPreferredSize(bool isEnabled, bool isDiscrete) {
// 这里根据设计图或者代码自行计算
return const Size(15, 40);
}
T start;
T end;
TextPainter labelTextPainter = TextPainter()
..textDirection = TextDirection.ltr;
@override
void paint(
PaintingContext context,
Offset center, {
required Animation<double> activationAnimation,
required Animation<double> enableAnimation,
bool? isDiscrete,
bool? isEnabled,
bool? isOnTop,
TextDirection? textDirection,
required SliderThemeData sliderTheme,
Thumb? thumb,
bool? isPressed,
}) {
final Canvas canvas = context.canvas;
final Paint strokePaint = Paint()
..color = sliderTheme.thumbColor ?? Colors.yellow
..strokeWidth = 3.0
..style = PaintingStyle.stroke;
canvas.drawCircle(center, 7.5, Paint()..color = Colors.white);
canvas.drawCircle(center, 7.5, strokePaint);
if (thumb == null) {
return;
}
// 以下就是在thumb下添加一个自定义labels
final value = thumb == Thumb.start ? start : end;
labelTextPainter.text = TextSpan(
text: value.toString(),
style: const TextStyle(fontSize: 14, color: Colors.black));
labelTextPainter.layout();
labelTextPainter.paint(
canvas,
center.translate(
-labelTextPainter.width / 2, labelTextPainter.height / 2));
}
}