@@ -2154,6 +2154,102 @@ void main() {
2154
2154
expect (value, 0.5 );
2155
2155
}, variant: const TargetPlatformVariant (< TargetPlatform > { TargetPlatform .iOS, TargetPlatform .macOS }));
2156
2156
2157
+ testWidgets ('In directional nav, Slider can be navigated out of by using up and down arrows' , (WidgetTester tester) async {
2158
+ const Map <ShortcutActivator , Intent > shortcuts = < ShortcutActivator , Intent > {
2159
+ SingleActivator (LogicalKeyboardKey .arrowLeft): DirectionalFocusIntent (TraversalDirection .left),
2160
+ SingleActivator (LogicalKeyboardKey .arrowRight): DirectionalFocusIntent (TraversalDirection .right),
2161
+ SingleActivator (LogicalKeyboardKey .arrowDown): DirectionalFocusIntent (TraversalDirection .down),
2162
+ SingleActivator (LogicalKeyboardKey .arrowUp): DirectionalFocusIntent (TraversalDirection .up),
2163
+ };
2164
+
2165
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy .alwaysTraditional;
2166
+ double topSliderValue = 0.5 ;
2167
+ double bottomSliderValue = 0.5 ;
2168
+ await tester.pumpWidget (
2169
+ MaterialApp (
2170
+ home: Shortcuts (
2171
+ shortcuts: shortcuts,
2172
+ child: Material (
2173
+ child: Center (
2174
+ child: StatefulBuilder (builder: (BuildContext context, StateSetter setState) {
2175
+ return MediaQuery (
2176
+ data: const MediaQueryData (navigationMode: NavigationMode .directional),
2177
+ child: Column (
2178
+ children: < Widget > [
2179
+ Slider (
2180
+ value: topSliderValue,
2181
+ onChanged: (double newValue) {
2182
+ setState (() {
2183
+ topSliderValue = newValue;
2184
+ });
2185
+ },
2186
+ autofocus: true ,
2187
+ ),
2188
+ Slider (
2189
+ value: bottomSliderValue,
2190
+ onChanged: (double newValue) {
2191
+ setState (() {
2192
+ bottomSliderValue = newValue;
2193
+ });
2194
+ },
2195
+ ),
2196
+ ]
2197
+ ),
2198
+ );
2199
+ }),
2200
+ ),
2201
+ ),
2202
+ ),
2203
+ ),
2204
+ );
2205
+ await tester.pumpAndSettle ();
2206
+
2207
+ // The top slider is auto-focused and can be adjusted with left and right arrow keys.
2208
+ await tester.sendKeyEvent (LogicalKeyboardKey .arrowRight);
2209
+ await tester.pumpAndSettle ();
2210
+ expect (topSliderValue, 0.55 , reason: 'focused top Slider increased after first arrowRight' );
2211
+ expect (bottomSliderValue, 0.5 , reason: 'unfocused bottom Slider unaffected by first arrowRight' );
2212
+
2213
+ await tester.sendKeyEvent (LogicalKeyboardKey .arrowLeft);
2214
+ await tester.pumpAndSettle ();
2215
+ expect (topSliderValue, 0.5 , reason: 'focused top Slider decreased after first arrowLeft' );
2216
+ expect (bottomSliderValue, 0.5 , reason: 'unfocused bottom Slider unaffected by first arrowLeft' );
2217
+
2218
+ // Pressing the down-arrow key moves focus down to the bottom slider
2219
+ await tester.sendKeyEvent (LogicalKeyboardKey .arrowDown);
2220
+ await tester.pumpAndSettle ();
2221
+ expect (topSliderValue, 0.5 , reason: 'arrowDown unfocuses top Slider, does not alter its value' );
2222
+ expect (bottomSliderValue, 0.5 , reason: 'arrowDown focuses bottom Slider, does not alter its value' );
2223
+
2224
+ // The bottom slider is now focused and can be adjusted with left and right arrow keys.
2225
+ await tester.sendKeyEvent (LogicalKeyboardKey .arrowRight);
2226
+ await tester.pumpAndSettle ();
2227
+ expect (topSliderValue, 0.5 , reason: 'unfocused top Slider unaffected by second arrowRight' );
2228
+ expect (bottomSliderValue, 0.55 , reason: 'focused bottom Slider increased by second arrowRight' );
2229
+
2230
+ await tester.sendKeyEvent (LogicalKeyboardKey .arrowLeft);
2231
+ await tester.pumpAndSettle ();
2232
+ expect (topSliderValue, 0.5 , reason: 'unfocused top Slider unaffected by second arrowLeft' );
2233
+ expect (bottomSliderValue, 0.5 , reason: 'focused bottom Slider decreased by second arrowLeft' );
2234
+
2235
+ // Pressing the up-arrow key moves focus back up to the top slider
2236
+ await tester.sendKeyEvent (LogicalKeyboardKey .arrowUp);
2237
+ await tester.pumpAndSettle ();
2238
+ expect (topSliderValue, 0.5 , reason: 'arrowUp focuses top Slider, does not alter its value' );
2239
+ expect (bottomSliderValue, 0.5 , reason: 'arrowUp unfocuses bottom Slider, does not alter its value' );
2240
+
2241
+ // The top slider is now focused again and can be adjusted with left and right arrow keys.
2242
+ await tester.sendKeyEvent (LogicalKeyboardKey .arrowRight);
2243
+ await tester.pumpAndSettle ();
2244
+ expect (topSliderValue, 0.55 , reason: 'focused top Slider increased after third arrowRight' );
2245
+ expect (bottomSliderValue, 0.5 , reason: 'unfocused bottom Slider unaffected by third arrowRight' );
2246
+
2247
+ await tester.sendKeyEvent (LogicalKeyboardKey .arrowLeft);
2248
+ await tester.pumpAndSettle ();
2249
+ expect (topSliderValue, 0.5 , reason: 'focused top Slider decreased after third arrowRight' );
2250
+ expect (bottomSliderValue, 0.5 , reason: 'unfocused bottom Slider unaffected by third arrowRight' );
2251
+ });
2252
+
2157
2253
testWidgets ('Slider gains keyboard focus when it gains semantics focus on Windows' , (WidgetTester tester) async {
2158
2254
final SemanticsTester semantics = SemanticsTester (tester);
2159
2255
final SemanticsOwner semanticsOwner = tester.binding.pipelineOwner.semanticsOwner! ;
0 commit comments