How to draw custom thumb in Flutter Slider?
In Flutter Slider, you can easily customize the sliders’ thumb to achieve various scenarios. This article will assist you in creating a volume bar, as shown in the following image.
Step 1: Add the Syncfusion® Flutter Sliders package to your dependencies in the pubspec.yaml file.
Step 2: Initialize the SfSlider widget as a child of any widget. Now, set the values for the SfSlider.min and SfSlider.max properties. The value of the SfSlider.value property should be between the min and max values. Set the _CustomThumbShape() to the SfSlider.thumbShape property.
double _value = 50.0; @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Row( children: [ SizedBox( width: 30, child: Center( child: Text( '${_value.toInt()}', style: TextStyle(color: _value > 90 ? Colors.red : Colors.black), )), ), Expanded( child: SfSliderTheme( data: SfSliderThemeData( trackCornerRadius: 7.5, activeTrackHeight: 15, inactiveTrackHeight: 15, overlayRadius: 0.0), child: SfSlider( min: 0.0, max: 100.0, value: _value, thumbShape: _CustomThumbShape(), onChanged: (dynamic value) { setState(() { _value = value; }); }, ), ), ), ], ), ), ); }
Step 3: Extend the SfThumbShape class to create a custom shape. Override the paint method and draw a shape that you want. You can obtain the current value, thumb pixel value, text direction, and theme data values as a paint methods’ parameters. Using these values, created a volume slider.
class _CustomThumbShape extends SfThumbShape { // Converts degree to radians. double degreeToRadians(num deg) => deg * (pi / 180.0); @override void paint(PaintingContext context, Offset center, {required RenderBox parentBox, required RenderBox? child, required SfSliderThemeData themeData, SfRangeValues? currentValues, dynamic currentValue, required Paint? paint, required Animation<double> enableAnimation, required TextDirection textDirection, required SfThumb? thumb}) { final Path path = Path(); final Paint paint = Paint() ..color = currentValue > 90 ? Colors.red : Colors.black ..style = PaintingStyle.fill ..strokeWidth = 2; path.moveTo(center.dx, center.dy - 10); path.lineTo(center.dx, center.dy + 10); path.lineTo(center.dx - 5, center.dy + 3); path.lineTo(center.dx - 10, center.dy + 3); path.lineTo(center.dx - 10, center.dy - 3); path.lineTo(center.dx - 5, center.dy - 3); path.close(); context.canvas.drawPath(path, paint); paint ..style = PaintingStyle.stroke ..strokeWidth = 2; path.reset(); if (currentValue == 0) { paint.color = Colors.red; path.moveTo(center.dx + 3, center.dy - 8); path.lineTo(center.dx - 8, center.dy + 8); } else { for (int i = 1; i <= 3; i++) { path.moveTo(center.dx + (i * 2), center.dy); path.arcTo( Rect.fromCenter( center: Offset(center.dx + (i * 2), center.dy), width: i * 3, height: i * 6), degreeToRadians(270), degreeToRadians(180), true); if (i * 33 > currentValue) { break; } } } context.canvas.drawPath(path, paint); } }
Output
Check the following links for more features in Syncfusion® Flutter Sliders:
Live samples