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
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
1you 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); } } 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.
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); } }
