Skip to content

Commit e2fdf18

Browse files
committed
Fix discrete Slider and RangeSlider to enforce thumb height padding when the track shape is non-rounded
1 parent 04616f8 commit e2fdf18

File tree

4 files changed

+93
-9
lines changed

4 files changed

+93
-9
lines changed

packages/flutter/lib/src/material/range_slider.dart

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,8 +1491,7 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix
14911491
sliderTheme: _sliderTheme,
14921492
isDiscrete: isDiscrete,
14931493
);
1494-
final double padding =
1495-
isDiscrete || _sliderTheme.rangeTrackShape!.isRounded ? trackRect.height : 0.0;
1494+
final double padding = _sliderTheme.rangeTrackShape!.isRounded ? trackRect.height : 0.0;
14961495
final double thumbYOffset = trackRect.center.dy;
14971496
final double startThumbPosition =
14981497
isDiscrete
@@ -1585,16 +1584,16 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix
15851584
_sliderTheme.rangeTickMarkShape!
15861585
.getPreferredSize(isEnabled: isEnabled, sliderTheme: _sliderTheme)
15871586
.width;
1588-
final double padding = trackRect.height;
1589-
final double adjustedTrackWidth = trackRect.width - padding;
1587+
final double discreteTrackPadding = trackRect.height;
1588+
final double adjustedTrackWidth = trackRect.width - discreteTrackPadding;
15901589
// If the tick marks would be too dense, don't bother painting them.
15911590
if (adjustedTrackWidth / divisions! >= 3.0 * tickMarkWidth) {
15921591
final double dy = trackRect.center.dy;
15931592
for (int i = 0; i <= divisions!; i++) {
15941593
final double value = i / divisions!;
15951594
// The ticks are mapped to be within the track, so the tick mark width
15961595
// must be subtracted from the track width.
1597-
final double dx = trackRect.left + value * adjustedTrackWidth + padding / 2;
1596+
final double dx = trackRect.left + value * adjustedTrackWidth + discreteTrackPadding / 2;
15981597
final Offset tickMarkOffset = Offset(dx, dy);
15991598
_sliderTheme.rangeTickMarkShape!.paint(
16001599
context,

packages/flutter/lib/src/material/slider.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1739,8 +1739,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
17391739
sliderTheme: _sliderTheme,
17401740
isDiscrete: isDiscrete,
17411741
);
1742-
final double padding =
1743-
isDiscrete || _sliderTheme.trackShape!.isRounded ? trackRect.height : 0.0;
1742+
final double padding = _sliderTheme.trackShape!.isRounded ? trackRect.height : 0.0;
17441743
final double thumbPosition =
17451744
isDiscrete
17461745
? trackRect.left + visualPosition * (trackRect.width - padding) + padding / 2
@@ -1821,15 +1820,16 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
18211820
_sliderTheme.tickMarkShape!
18221821
.getPreferredSize(isEnabled: isInteractive, sliderTheme: _sliderTheme)
18231822
.width;
1824-
final double adjustedTrackWidth = trackRect.width - padding;
1823+
final double discreteTrackPadding = trackRect.height;
1824+
final double adjustedTrackWidth = trackRect.width - discreteTrackPadding;
18251825
// If the tick marks would be too dense, don't bother painting them.
18261826
if (adjustedTrackWidth / divisions! >= 3.0 * tickMarkWidth) {
18271827
final double dy = trackRect.center.dy;
18281828
for (int i = 0; i <= divisions!; i++) {
18291829
final double value = i / divisions!;
18301830
// The ticks are mapped to be within the track, so the tick mark width
18311831
// must be subtracted from the track width.
1832-
final double dx = trackRect.left + value * adjustedTrackWidth + padding / 2;
1832+
final double dx = trackRect.left + value * adjustedTrackWidth + discreteTrackPadding / 2;
18331833
final Offset tickMarkOffset = Offset(dx, dy);
18341834
_sliderTheme.tickMarkShape!.paint(
18351835
context,

packages/flutter/test/material/range_slider_test.dart

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3093,4 +3093,47 @@ void main() {
30933093
..rrect(rrect: RRect.fromLTRBR(8.0, 7.0, 792.0, 13.0, const Radius.circular(2.0))),
30943094
);
30953095
});
3096+
3097+
// Regression test for hhttps://github.com/flutter/flutter/issues/161805
3098+
testWidgets('Discrete RangeSlider does not apply thumb padding in a non-rounded track shape', (
3099+
WidgetTester tester,
3100+
) async {
3101+
// The default track left and right padding.
3102+
const double sliderPadding = 24.0;
3103+
final ThemeData theme = ThemeData(
3104+
sliderTheme: const SliderThemeData(
3105+
// Thumb padding is applied based on the track height.
3106+
trackHeight: 100,
3107+
rangeTrackShape: RectangularRangeSliderTrackShape(),
3108+
),
3109+
);
3110+
3111+
await tester.pumpWidget(
3112+
MaterialApp(
3113+
theme: theme,
3114+
home: Material(
3115+
child: SizedBox(
3116+
width: 300,
3117+
child: RangeSlider(
3118+
values: const RangeValues(0, 100),
3119+
max: 100,
3120+
divisions: 100,
3121+
onChanged: (RangeValues value) {},
3122+
),
3123+
),
3124+
),
3125+
),
3126+
);
3127+
3128+
final MaterialInkController material = Material.of(tester.element(find.byType(RangeSlider)));
3129+
3130+
expect(
3131+
material,
3132+
paints
3133+
// Start thumb.
3134+
..circle(x: sliderPadding, y: 300.0, color: theme.colorScheme.primary)
3135+
// End thumb.
3136+
..circle(x: 800.0 - sliderPadding, y: 300.0, color: theme.colorScheme.primary),
3137+
);
3138+
});
30963139
}

packages/flutter/test/material/slider_test.dart

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5328,4 +5328,46 @@ void main() {
53285328
await tester.pumpAndSettle();
53295329
expect(log.last, const Offset(400.0, 300.0));
53305330
});
5331+
5332+
// Regression test for hhttps://github.com/flutter/flutter/issues/161805
5333+
testWidgets('Discrete Slider does not apply thumb padding in a non-rounded track shape', (
5334+
WidgetTester tester,
5335+
) async {
5336+
// The default track left and right padding.
5337+
const double sliderPadding = 24.0;
5338+
final ThemeData theme = ThemeData(
5339+
sliderTheme: const SliderThemeData(
5340+
// Thumb padding is applied based on the track height.
5341+
trackHeight: 100,
5342+
trackShape: RectangularSliderTrackShape(),
5343+
),
5344+
);
5345+
5346+
Widget buildSlider({required double value}) {
5347+
return MaterialApp(
5348+
theme: theme,
5349+
home: Material(
5350+
child: SizedBox(
5351+
width: 300,
5352+
child: Slider(value: value, max: 100, divisions: 100, onChanged: (double value) {}),
5353+
),
5354+
),
5355+
);
5356+
}
5357+
5358+
await tester.pumpWidget(buildSlider(value: 0));
5359+
5360+
MaterialInkController material = Material.of(tester.element(find.byType(Slider)));
5361+
5362+
expect(material, paints..circle(x: sliderPadding, y: 300.0, color: theme.colorScheme.primary));
5363+
5364+
await tester.pumpWidget(buildSlider(value: 100));
5365+
await tester.pumpAndSettle();
5366+
5367+
material = Material.of(tester.element(find.byType(Slider)));
5368+
expect(
5369+
material,
5370+
paints..circle(x: 800.0 - sliderPadding, y: 300.0, color: theme.colorScheme.primary),
5371+
);
5372+
});
53315373
}

0 commit comments

Comments
 (0)