
移动小样
V1
2022/12/10阅读:69主题:默认主题
Flutter-分段滑块
简述
首先说下非常抱歉,因为个人问题,已有一个多月没有更新了,上周五有个小姐姐问我一个分段滑块的效果,这里就简单写下一个小样作为一个记录。
效果图

分析
其实自带的Slider基本能满足我们的需求,但是这个小姐姐的需要是后台会返回一个数组段比如说[0,10,30,60,100,150],这个滑块只能滑动到数组段中的值,其实这个简单的方式就是直接在slider滑动的时候,判断当前value距离数组段中那个值最接近,然后直接设置slider的值为这个值就可以了。
代码实现
///在数组段中找到当前与value最接近的值
void updateValue(double value) {
var minValue = double.infinity;
var result = 0.0;
for (var element in widget.divisions) {
double m = value - element;
if (m.abs() < minValue) {
result = element;
minValue = m.abs();
}
}
if (_value == result) {
return;
}
setState(() {
_value = result;
if (widget.onChanged != null) {
widget.onChanged?.call(_value);
}
});
}
完整代码
import 'package:flutter/material.dart';
///分段滑块
class DivisionsSlider extends StatefulWidget {
const DivisionsSlider({
Key? key,
required this.value,
required this.onChanged,
required this.divisions,
this.onChangeStart,
this.onChangeEnd,
this.min = 0.0,
this.max = 1.0,
this.label,
this.activeColor,
this.inactiveColor,
this.thumbColor,
this.mouseCursor,
this.semanticFormatterCallback,
this.focusNode,
this.autofocus = false,
}) : super(key: key);
final double value;
final ValueChanged<double>? onChanged;
final ValueChanged<double>? onChangeStart;
final ValueChanged<double>? onChangeEnd;
final double min;
final double max;
final String? label;
final Color? activeColor;
final Color? inactiveColor;
final Color? thumbColor;
final MouseCursor? mouseCursor;
final SemanticFormatterCallback? semanticFormatterCallback;
final FocusNode? focusNode;
final bool autofocus;
final List<double> divisions;
@override
State<DivisionsSlider> createState() => _DivisionsSliderState();
}
class _DivisionsSliderState extends State<DivisionsSlider> {
late double _value;
@override
void initState() {
super.initState();
_value = widget.value;
}
@override
Widget build(BuildContext context) {
return Slider(
value: _value,
onChanged: (value) {
updateValue(value);
},
onChangeStart: widget.onChangeStart,
onChangeEnd: widget.onChangeEnd,
min: widget.min,
max: widget.max,
label: widget.label,
activeColor: widget.activeColor,
inactiveColor: widget.inactiveColor,
thumbColor: widget.thumbColor,
mouseCursor: widget.mouseCursor,
semanticFormatterCallback: widget.semanticFormatterCallback,
focusNode: widget.focusNode,
autofocus: widget.autofocus,
);
}
void updateValue(double value) {
var minValue = double.infinity;
var result = 0.0;
for (var element in widget.divisions) {
double min = (value - element).abs();
if (min < minValue) {
result = element;
minValue = min;
}
}
if (_value == result) {
return;
}
setState(() {
_value = result;
if (widget.onChanged != null) {
widget.onChanged?.call(_value);
}
});
}
}
使用控件
DivisionsSlider(
value: defaultValue,
onChanged: (value) {
defaultValue = value;
setState(() {});
},
divisions: const [0, 10, 30, 60, 100, 150],
max: 150,
),
作者介绍

移动小样
V1