Reputation: 1292
My slider jumps from one value to another. How can I make it movable in between the values or make it smoother in Flutter?
Column(
children: <Widget>[
RangeSlider(
min: 1,
max: 40,
divisions: 4,
onChanged: onChange,
values: RangeValues((startValue ?? 1).toDouble(), (endValue ?? 40).toDouble()),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text('Beginner', style: Theme.of(context).textTheme.body2),
Text('Ameateur', style: Theme.of(context).textTheme.body2),
Text('Intermediate', style: Theme.of(context).textTheme.body2),
Text('Advanced', style: Theme.of(context).textTheme.body2),
Text('Professional', style: Theme.of(context).textTheme.body2),
],
),
],
);
Upvotes: 1
Views: 4075
Reputation: 3034
The divisions
property makes it jump in 4 steps. Remove that and the slider will be fluent.
RangeSlider(
min: 1,
max: 40,
// divisions: 4, // <-- remove this
onChanged: onChange,
values: RangeValues((startValue ?? 1).toDouble(), (endValue ?? 40).toDouble()),
),
Question is actually about having the thumbs being fluent while still snapping to discrete points on the range slider. The Flutter widget does not provide an easy way to achieve that, so there are two options.
The first is to create a new widget to get the exact behavior you need. This might be the best option if you need a lot of customisation.
Use the onChangeEnd
callback in addition to the onChanged
callback to update the position of the thumb correctly. The onChanged
callback is used to make it fluent, while the onChangeEnd
callback is used to snap the thumb to the closest discrete value based on a division count.
A possible implementation (the discretize method can possibly be shorter/improved):
class _RangeSliderExampleState extends State<RangeSliderExample> {
double _startValue;
double _endValue;
static const double _minValue = 1;
static const double _maxValue = 40;
static const double _divisions = 4;
@override
Widget build(BuildContext context) {
return RangeSlider(
min: _minValue,
max: _maxValue,
onChanged: (values) {
setState(() {
_startValue = values.start;
_endValue = values.end;
});
},
onChangeEnd: (values) {
setState(() {
_startValue = _discretize(values.start, _divisions);
_endValue = _discretize(values.end, _divisions);
});
},
values: RangeValues((_startValue ?? 1).toDouble(),
(_endValue ?? 40).toDouble()),
);
}
double _discretize(double value, double divisions) {
double x = value - _minValue;
double range = _maxValue - _minValue;
double result = x / range;
return (result * divisions).round() / divisions * range + _minValue;
}
}
Upvotes: 6