From d99e5fdd2c3762e45860358ecfcbbe0fca994b81 Mon Sep 17 00:00:00 2001 From: Taha Tesser Date: Fri, 23 Jun 2023 00:20:40 +0300 Subject: [PATCH] Fix `Slider` overlay remains when unfocused (#129115) fixes https://github.com/flutter/flutter/issues/129016 --- packages/flutter/lib/src/material/slider.dart | 5 +-- .../flutter/test/material/slider_test.dart | 44 ++++++++++++------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/packages/flutter/lib/src/material/slider.dart b/packages/flutter/lib/src/material/slider.dart index 9790cea7093..6680aaa144b 100644 --- a/packages/flutter/lib/src/material/slider.dart +++ b/packages/flutter/lib/src/material/slider.dart @@ -1530,10 +1530,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin { onChangeEnd?.call(_discretize(_currentDragValue)); _active = false; _currentDragValue = 0.0; - if (!hasFocus) { - _state.overlayController.reverse(); - } - + _state.overlayController.reverse(); if (showValueIndicator && _state.interactionTimer == null) { _state.valueIndicatorController.reverse(); } diff --git a/packages/flutter/test/material/slider_test.dart b/packages/flutter/test/material/slider_test.dart index cfeee60744a..a8bf69325cc 100644 --- a/packages/flutter/test/material/slider_test.dart +++ b/packages/flutter/test/material/slider_test.dart @@ -1945,6 +1945,7 @@ void main() { double value = 0.5; final ThemeData theme = ThemeData(useMaterial3: true); final Key sliderKey = UniqueKey(); + final FocusNode focusNode = FocusNode(); Widget buildApp({bool enabled = true}) { return MaterialApp( @@ -1953,8 +1954,9 @@ void main() { child: Center( child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) { return Slider( - value: value, key: sliderKey, + value: value, + focusNode: focusNode, onChanged: enabled ? (double newValue) { setState(() { @@ -1994,7 +1996,18 @@ void main() { await drag.up(); await tester.pumpAndSettle(); - // Slider still has overlay when stopped dragging. + // Slider without focus doesn't have overlay when enabled and dragged. + expect(focusNode.hasFocus, false); + expect( + Material.of(tester.element(find.byType(Slider))), + isNot(paints..circle(color: theme.colorScheme.primary.withOpacity(0.12))), + ); + + // Slider has overlay when enabled, dragged and focused. + focusNode.requestFocus(); + await tester.pumpAndSettle(); + + expect(focusNode.hasFocus, true); expect( Material.of(tester.element(find.byType(Slider))), paints..circle(color: theme.colorScheme.primary.withOpacity(0.12)), @@ -2005,6 +2018,7 @@ void main() { tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; double value = 0.5; final Key sliderKey = UniqueKey(); + final FocusNode focusNode = FocusNode(); Widget buildApp({bool enabled = true}) { return MaterialApp( @@ -2012,8 +2026,9 @@ void main() { child: Center( child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) { return Slider( - value: value, key: sliderKey, + value: value, + focusNode: focusNode, overlayColor: MaterialStateColor.resolveWith((Set states) { if (states.contains(MaterialState.dragged)) { return Colors.lime[500]!; @@ -2060,10 +2075,11 @@ void main() { await drag.up(); await tester.pumpAndSettle(); - // Slider still has overlay when stopped dragging. + // Slider without focus doesn't have overlay when enabled and dragged. + expect(focusNode.hasFocus, false); expect( Material.of(tester.element(find.byType(Slider))), - paints..circle(color: Colors.lime[500]), + isNot(paints..circle(color: Colors.lime[500])), ); }); @@ -3495,14 +3511,7 @@ void main() { await gesture.up(); await tester.pumpAndSettle(); expect(focusNode.hasFocus, true); - expect( - Material.of(tester.element(find.byType(Slider))), - paints..circle(color: overlayColor), - ); - - focusNode.unfocus(); - await tester.pumpAndSettle(); - expect(focusNode.hasFocus, false); + // Overlay is removed when adjusted with a tap. expect( Material.of(tester.element(find.byType(Slider))), isNot(paints..circle(color: overlayColor)), @@ -3796,6 +3805,7 @@ void main() { double value = 0.5; final ThemeData theme = ThemeData(); final Key sliderKey = UniqueKey(); + final FocusNode focusNode = FocusNode(); Widget buildApp({bool enabled = true}) { return MaterialApp( @@ -3803,8 +3813,9 @@ void main() { child: Center( child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) { return Slider( - value: value, key: sliderKey, + value: value, + focusNode: focusNode, onChanged: enabled ? (double newValue) { setState(() { @@ -3844,10 +3855,11 @@ void main() { await drag.up(); await tester.pumpAndSettle(); - // Slider still has overlay when stopped dragging. + // Slider without focus doesn't have overlay when enabled and dragged. + expect(focusNode.hasFocus, false); expect( Material.of(tester.element(find.byType(Slider))), - paints..circle(color: theme.colorScheme.primary.withOpacity(0.12)), + isNot(paints..circle(color: theme.colorScheme.primary.withOpacity(0.12))), ); }); });