先上效果圖:
因?yàn)轫?xiàng)目需求,所以自定義一個(gè)slider.
使用:
MySliderUtil(
minValue: (widget.model?.durableNow ?? 0) / 100, //可滑動(dòng)的最小值
valueBlock: (value) {
print(value);
),
具體代碼
class MySliderUtil extends StatefulWidget {
MySliderUtil({
Key? key,
required this.valueBlock,
this.minValue = 0.0,
}) : super(key: key);
final ValueBlock valueBlock;
final double minValue;
@override
_MySliderUtilState createState() => _MySliderUtilState();
}
class _MySliderUtilState extends State<MySliderUtil> {
double _value = 0.0;
@override
void initState() {
// TODO: implement initState
super.initState();
_value = widget.minValue;
}
@override
Widget build(BuildContext context) {
return SizedBox(
height: SAdapt.width(28),
child: Stack(
children: [
Positioned(
top: 8.w,
child: Container(
width: 12.w,
height: 12.w,
decoration: BoxDecoration(
color: get826DD4Color(),
borderRadius: BorderRadius.circular(10),
),
),
),
Positioned(
right: 0.w,
top: 8.w,
child: Container(
width: 12.w,
height: 12.w,
decoration: BoxDecoration(
color: getF5F9FCColor(),
borderRadius: BorderRadius.circular(10),
),
),
),
Container(
margin: EdgeInsets.only(left: 11.5.w, right: 11.5.w),
child: SliderTheme(
data: SliderThemeData(
//去掉長按光暈
overlayColor: Colors.transparent,
trackHeight: SAdapt.width(2),
inactiveTrackColor: getF5F9FCColor(),
activeTrackColor: get826DD4Color(), // Color(0xFF81C359),
trackShape: const CustomTrackShape(),
thumbShape: SquareSliderComponentShape(),
),
child: Slider(
value: _value < 0 ? 0 : _value,
onChangeStart: (double value) {},
onChangeEnd: (double value) {
if (value < widget.minValue) {
widget.valueBlock(widget.minValue);
return;
}
//每次借宿后都會(huì)走
// 拖拽跳轉(zhuǎn)
setState(() {
_value = value;
});
widget.valueBlock(value);
},
onChanged: (double value) {
if (value < widget.minValue) {
_value = widget.minValue;
} else {
_value = value;
}
setState(() {});
},
),
),
),
],
),
);
}
}
上面的其實(shí)就可以用了,但是需求的滑塊需要我們自定義,又遇到了別的問題,一步一步來~!
使用的時(shí)候發(fā)現(xiàn)滑塊選中的偏移量有一些問題,所以定義了如下的RoundedRectSliderTrackShape
:
class CustomTrackShape extends RoundedRectSliderTrackShape {
const CustomTrackShape();
@override
Rect getPreferredRect({
required RenderBox parentBox,
Offset offset = Offset.zero,
required SliderThemeData sliderTheme,
bool isEnabled = false,
bool isDiscrete = false,
}) {
final double trackHeight = sliderTheme.trackHeight!;
final double trackWidth = parentBox.size.width;
final double trackLeft = offset.dx;
final double trackTop =
offset.dy + (parentBox.size.height - trackHeight) / 2;
return Rect.fromLTWH(trackLeft, trackTop, trackWidth, trackHeight);
}
@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 = 0,
}) {
super.paint(
context,
offset,
parentBox: parentBox,
sliderTheme: sliderTheme,
enableAnimation: enableAnimation,
textDirection: textDirection,
thumbCenter: thumbCenter,
//增加選中滑塊的高度,系統(tǒng)默認(rèn)+2· 給0就不加高了
additionalActiveTrackHeight: 0,
);
}
}
最后我們來封裝滑塊的樣式:
class SquareSliderComponentShape extends SliderComponentShape {
@override
Size getPreferredSize(bool isEnabled, bool isDiscrete) {
return Size(SAdapt.width(28), SAdapt.width(28));
}
@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;
canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromCenter(
center: center, width: SAdapt.width(28), height: SAdapt.width(28)),
const Radius.circular(14),
),
Paint()..color = Colors.white,
);
//背景的線 實(shí)線
Paint line = Paint()
..color = get826DD4Color()
..strokeCap = StrokeCap.round
..style = PaintingStyle.stroke
..strokeWidth = SAdapt.width(2);
// 畫圓方法
canvas.drawCircle(center, SAdapt.width(14), line);
}
}
如果對(duì)你有幫助的話,希望能給我點(diǎn)個(gè)贊,哈哈!
后續(xù)
項(xiàng)目里好多樣式的滑塊,后來引用了一個(gè)第三方:syncfusion_flutter_sliders
,然后按照你的需求再進(jìn)行修改就可以了.
進(jìn)度條 兩個(gè)拖動(dòng)
#https://pub.dev/packages/syncfusion_flutter_sliders/versions
syncfusion_flutter_sliders: ^20.3.52
修改進(jìn)度條樣式
# https://pub.dev/packages/syncfusion_flutter_core
syncfusion_flutter_core: ^20.3.52
有各式各樣的,大致都能滿足我們使用的需求.下面是文檔:
https://help.syncfusion.com/flutter/slider/thumb-and-overlay
貼兩個(gè)使用的例子:
這個(gè)是雙滑塊的
先上效果圖
代碼:
Container(
margin: EdgeInsets.only(
bottom: SAdapt.width(15),
left: SAdapt.width(15),
right: SAdapt.width(15),
),
child: Stack(
children: [
Positioned(
// right: 21.w,
left: 14.w,
top: 19.w,
child: Container(
width: 12.w,
height: 12.w,
decoration: BoxDecoration(
color: getF5F9FCColor(),
borderRadius: BorderRadius.circular(10),
),
),
),
Positioned(
// right: 21.w,
right: 14.w,
top: 19.w,
child: Container(
width: 12.w,
height: 12.w,
decoration: BoxDecoration(
color: getF5F9FCColor(),
borderRadius: BorderRadius.circular(10),
),
),
),
SfRangeSliderTheme(
data: SfRangeSliderThemeData(
overlayColor: Colors.transparent,
thumbColor: Colors.white,
thumbRadius: 12,
thumbStrokeWidth: SAdapt.width(2),
thumbStrokeColor: get826DD4Color(),
activeTrackHeight: SAdapt.width(2),
inactiveTrackHeight: SAdapt.width(2),
activeTrackColor: get826DD4Color(),
),
child: SfRangeSlider(
min: 0.0,
max: widget.maxRang,
values: _values,
interval: 20,
showTicks: false,
showLabels: false,
enableTooltip: false,
minorTicksPerInterval: 1,
// activeColor: get826DD4Color(),
inactiveColor: getF5F9FCColor(),
onChanged: (SfRangeValues values) {
setState(() {
selectedStart = int.parse(moneyDoubleOrInt(
(_values.start).toDouble(),
postion: 0));
selectedEnd = int.parse(moneyDoubleOrInt(
(_values.end).toDouble(),
postion: 0));
// if (selectedEnd == selectedStart) {
// _values = const SfRangeValues(0, 1);
// } else {
_values = values;
// }
});
},
),
),
],
),
),
這個(gè)是單滑塊的效果圖跟我們之前使用的 一樣,但是他的最小值定義完之后,就不是從0開始了,你給完最小值 就是初始階段,而不是可使用的最小值.我自定義的起始值就是0,然后在給一個(gè)最小值是顯示出來的,只可以在我給的最小值之間和最大值之間滑動(dòng)
Container(
margin: EdgeInsets.only(
left: SAdapt.width(10),
right: SAdapt.width(10),
),
child: Stack(
children: [
Positioned(
// right: 21.w,
left: 14.w,
top: 19.w,
child: Container(
width: 12.w,
height: 12.w,
decoration: BoxDecoration(
color: get826DD4Color(),
borderRadius: BorderRadius.circular(10),
),
),
),
Positioned(
// right: 21.w,
right: 14.w,
top: 19.w,
child: Container(
width: 12.w,
height: 12.w,
decoration: BoxDecoration(
color: getF5F9FCColor(),
borderRadius: BorderRadius.circular(10),
),
),
),
SfSliderTheme(
data: SfSliderThemeData(
//光暈顏色
overlayColor: Colors.transparent,
thumbColor: Colors.white,
thumbRadius: 12,
thumbStrokeWidth: SAdapt.width(2),
thumbStrokeColor: get826DD4Color(),
activeTrackHeight: SAdapt.width(2),
inactiveTrackHeight: SAdapt.width(2),
activeTrackColor: get826DD4Color(),
),
child: SfSlider(
min: 0.0,
max: 10.0,
value: sliderNum,
interval: 20,
minorTicksPerInterval: 1,
inactiveColor: getF5F9FCColor(),
onChanged: (newValue) {
setState(() {
sliderNum = newValue;
});
},
),
),
],
),
),