Skip to content

Commit d99e5fd

Browse files
authored
Fix Slider overlay remains when unfocused (#129115)
fixes flutter/flutter#129016
1 parent bec2436 commit d99e5fd

File tree

2 files changed

+29
-20
lines changed

2 files changed

+29
-20
lines changed

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1530,10 +1530,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
15301530
onChangeEnd?.call(_discretize(_currentDragValue));
15311531
_active = false;
15321532
_currentDragValue = 0.0;
1533-
if (!hasFocus) {
1534-
_state.overlayController.reverse();
1535-
}
1536-
1533+
_state.overlayController.reverse();
15371534
if (showValueIndicator && _state.interactionTimer == null) {
15381535
_state.valueIndicatorController.reverse();
15391536
}

packages/flutter/test/material/slider_test.dart

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1945,6 +1945,7 @@ void main() {
19451945
double value = 0.5;
19461946
final ThemeData theme = ThemeData(useMaterial3: true);
19471947
final Key sliderKey = UniqueKey();
1948+
final FocusNode focusNode = FocusNode();
19481949

19491950
Widget buildApp({bool enabled = true}) {
19501951
return MaterialApp(
@@ -1953,8 +1954,9 @@ void main() {
19531954
child: Center(
19541955
child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
19551956
return Slider(
1956-
value: value,
19571957
key: sliderKey,
1958+
value: value,
1959+
focusNode: focusNode,
19581960
onChanged: enabled
19591961
? (double newValue) {
19601962
setState(() {
@@ -1994,7 +1996,18 @@ void main() {
19941996
await drag.up();
19951997
await tester.pumpAndSettle();
19961998

1997-
// Slider still has overlay when stopped dragging.
1999+
// Slider without focus doesn't have overlay when enabled and dragged.
2000+
expect(focusNode.hasFocus, false);
2001+
expect(
2002+
Material.of(tester.element(find.byType(Slider))),
2003+
isNot(paints..circle(color: theme.colorScheme.primary.withOpacity(0.12))),
2004+
);
2005+
2006+
// Slider has overlay when enabled, dragged and focused.
2007+
focusNode.requestFocus();
2008+
await tester.pumpAndSettle();
2009+
2010+
expect(focusNode.hasFocus, true);
19982011
expect(
19992012
Material.of(tester.element(find.byType(Slider))),
20002013
paints..circle(color: theme.colorScheme.primary.withOpacity(0.12)),
@@ -2005,15 +2018,17 @@ void main() {
20052018
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
20062019
double value = 0.5;
20072020
final Key sliderKey = UniqueKey();
2021+
final FocusNode focusNode = FocusNode();
20082022

20092023
Widget buildApp({bool enabled = true}) {
20102024
return MaterialApp(
20112025
home: Material(
20122026
child: Center(
20132027
child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
20142028
return Slider(
2015-
value: value,
20162029
key: sliderKey,
2030+
value: value,
2031+
focusNode: focusNode,
20172032
overlayColor: MaterialStateColor.resolveWith((Set<MaterialState> states) {
20182033
if (states.contains(MaterialState.dragged)) {
20192034
return Colors.lime[500]!;
@@ -2060,10 +2075,11 @@ void main() {
20602075
await drag.up();
20612076
await tester.pumpAndSettle();
20622077

2063-
// Slider still has overlay when stopped dragging.
2078+
// Slider without focus doesn't have overlay when enabled and dragged.
2079+
expect(focusNode.hasFocus, false);
20642080
expect(
20652081
Material.of(tester.element(find.byType(Slider))),
2066-
paints..circle(color: Colors.lime[500]),
2082+
isNot(paints..circle(color: Colors.lime[500])),
20672083
);
20682084
});
20692085

@@ -3495,14 +3511,7 @@ void main() {
34953511
await gesture.up();
34963512
await tester.pumpAndSettle();
34973513
expect(focusNode.hasFocus, true);
3498-
expect(
3499-
Material.of(tester.element(find.byType(Slider))),
3500-
paints..circle(color: overlayColor),
3501-
);
3502-
3503-
focusNode.unfocus();
3504-
await tester.pumpAndSettle();
3505-
expect(focusNode.hasFocus, false);
3514+
// Overlay is removed when adjusted with a tap.
35063515
expect(
35073516
Material.of(tester.element(find.byType(Slider))),
35083517
isNot(paints..circle(color: overlayColor)),
@@ -3796,15 +3805,17 @@ void main() {
37963805
double value = 0.5;
37973806
final ThemeData theme = ThemeData();
37983807
final Key sliderKey = UniqueKey();
3808+
final FocusNode focusNode = FocusNode();
37993809

38003810
Widget buildApp({bool enabled = true}) {
38013811
return MaterialApp(
38023812
home: Material(
38033813
child: Center(
38043814
child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
38053815
return Slider(
3806-
value: value,
38073816
key: sliderKey,
3817+
value: value,
3818+
focusNode: focusNode,
38083819
onChanged: enabled
38093820
? (double newValue) {
38103821
setState(() {
@@ -3844,10 +3855,11 @@ void main() {
38443855
await drag.up();
38453856
await tester.pumpAndSettle();
38463857

3847-
// Slider still has overlay when stopped dragging.
3858+
// Slider without focus doesn't have overlay when enabled and dragged.
3859+
expect(focusNode.hasFocus, false);
38483860
expect(
38493861
Material.of(tester.element(find.byType(Slider))),
3850-
paints..circle(color: theme.colorScheme.primary.withOpacity(0.12)),
3862+
isNot(paints..circle(color: theme.colorScheme.primary.withOpacity(0.12))),
38513863
);
38523864
});
38533865
});

0 commit comments

Comments
 (0)