I am wondering how I can remove the default padding in Flutter Slider

Current output is like this, default padding of Slider is clearly visible

enter image description here

Here's my code::

 Positioned( child: Align( alignment: Alignment.bottomLeft, child: SliderTheme( data: SliderTheme.of(context).copyWith( trackHeight: 2.0, thumbColor: Colors.transparent, thumbShape: RoundSliderThumbShape(enabledThumbRadius: 0.0), ), child: Container( width: 380.0, height: 20.0, padding: EdgeInsets.all(0.0), decoration: BoxDecoration( border: Border.all(color: Colors.blueAccent) ), child: Slider( value: 50, min: 1, max: 100, divisions: 100, activeColor: colors.primaryRed, inactiveColor: Colors.white, onChanged: (double newValue) { print(newValue); }, ) ) ), ), ) 

4 Answers

SliderThemeData(overlayShape: SliderComponentShape.noOverlay) 

or

overlayShape: SliderComponentShape.noThumb 

Default padding is caused by thumb painting and overlay painting, by specifying these properties you will remove them, but you will get zero padding

1

you can fix it with custom trackShape like this:

add this line to SliderTheme data:

SliderTheme( data: SliderThemeData( // here trackShape: CustomTrackShape(), ), child: Slider( ), ), 

then inside CustomTrackShape() you must write this code:

class CustomTrackShape extends RoundedRectSliderTrackShape { @override Rect getPreferredRect({ required RenderBox parentBox, Offset offset = Offset.zero, required SliderThemeData sliderTheme, bool isEnabled = false, bool isDiscrete = false, }) { final trackHeight = sliderTheme.trackHeight; final trackLeft = offset.dx; final trackTop = offset.dy + (parentBox.size.height - trackHeight!) / 2; final trackWidth = parentBox.size.width; return Rect.fromLTWH(trackLeft, trackTop, trackWidth, trackHeight); } } 

enter image description here

1
 class _SfTrackShape extends SfTrackShape { @override Rect getPreferredRect( RenderBox parentBox, SfSliderThemeData themeData, Offset offset, {bool? isActive}) { final trackHeight = themeData.activeTrackHeight; final trackLeft = offset.dx; final trackTop = offset.dy + (parentBox.size.height - trackHeight) / 2; final trackWidth = parentBox.size.width; return Rect.fromLTWH(trackLeft, trackTop, trackWidth, trackHeight); } } 

While the accepted solution works reasonably well, the thumb looks too close to the edge when the slider position is at max or min.

enter image description here

You can address this by adding a custom thumbShape and overlayShape, which shift the thumb by a fraction of its radius as the slider position gets closer to the edges.

class CustomSlider extends StatelessWidget { @override Widget build(BuildContext context) { return SliderTheme( data: const SliderThemeData( trackShape: CustomSliderTrackShape(), thumbShape: CustomSliderThumbShape(), overlayShape: CustomSliderOverlayShape(), ), child: Slider( ), ); } } ... class CustomSliderTrackShape extends RoundedRectSliderTrackShape { const CustomSliderTrackShape(); @override Rect getPreferredRect({ required RenderBox parentBox, Offset offset = Offset.zero, required SliderThemeData sliderTheme, bool isEnabled = false, bool isDiscrete = false, }) { final trackHeight = sliderTheme.trackHeight; final trackLeft = offset.dx; final trackTop = offset.dy + (parentBox.size.height - trackHeight!) / 2; final trackWidth = parentBox.size.width; return Rect.fromLTWH(trackLeft, trackTop, trackWidth, trackHeight); } } class CustomSliderThumbShape extends RoundSliderThumbShape { const CustomSliderThumbShape({super.enabledThumbRadius = 10.0}); @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, }) { super.paint(context, center.translate(-(value - 0.5) / 0.5 * enabledThumbRadius, 0.0), activationAnimation: activationAnimation, enableAnimation: enableAnimation, isDiscrete: isDiscrete, labelPainter: labelPainter, parentBox: parentBox, sliderTheme: sliderTheme, textDirection: textDirection, value: value, textScaleFactor: textScaleFactor, sizeWithOverflow: sizeWithOverflow); } } class CustomSliderOverlayShape extends RoundSliderOverlayShape { final double thumbRadius; const CustomSliderOverlayShape({this.thumbRadius = 10.0}); @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, }) { super.paint( context, center.translate(-(value - 0.5) / 0.5 * thumbRadius, 0.0), activationAnimation: activationAnimation, enableAnimation: enableAnimation, isDiscrete: isDiscrete, labelPainter: labelPainter, parentBox: parentBox, sliderTheme: sliderTheme, textDirection: textDirection, value: value, textScaleFactor: textScaleFactor, sizeWithOverflow: sizeWithOverflow); } } 

More info with additional screenshots:

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.