diff --git a/packages/flutter/lib/src/material/dropdown.dart b/packages/flutter/lib/src/material/dropdown.dart index ef509e2815685..c3bf886f14296 100644 --- a/packages/flutter/lib/src/material/dropdown.dart +++ b/packages/flutter/lib/src/material/dropdown.dart @@ -1513,7 +1513,7 @@ class DropdownButtonFormField extends FormField { return InputDecorator( decoration: effectiveDecoration.copyWith(errorText: field.errorText), isEmpty: state.value == null, - isFocused: Focus.of(context)!.hasFocus, + isFocused: Focus.of(context).hasFocus, child: DropdownButtonHideUnderline( child: DropdownButton( items: items, diff --git a/packages/flutter/lib/src/widgets/focus_manager.dart b/packages/flutter/lib/src/widgets/focus_manager.dart index 4c224bae031e9..bbc5895bda0df 100644 --- a/packages/flutter/lib/src/widgets/focus_manager.dart +++ b/packages/flutter/lib/src/widgets/focus_manager.dart @@ -143,7 +143,7 @@ class FocusAttachment { assert(_node != null); if (isAttached) { assert(_node.context != null); - parent ??= Focus.of(_node.context!, nullOk: true, scopeOk: true); + parent ??= Focus.maybeOf(_node.context!, scopeOk: true); parent ??= _node.context!.owner!.focusManager.rootScope; assert(parent != null); parent._reparent(_node); @@ -1005,7 +1005,7 @@ class FocusNode with DiagnosticableTreeMixin, ChangeNotifier { _manager?.primaryFocus?._setAsFocusedChildForScope(); } if (oldScope != null && child.context != null && child.enclosingScope != oldScope) { - FocusTraversalGroup.of(child.context!, nullOk: true)?.changedScope(node: child, oldScope: oldScope); + FocusTraversalGroup.maybeOf(child.context!)?.changedScope(node: child, oldScope: oldScope); } if (child._requestFocusWhenReparented) { child._doRequestFocus(findFirstFocus: true); @@ -1145,19 +1145,19 @@ class FocusNode with DiagnosticableTreeMixin, ChangeNotifier { /// [FocusTraversalPolicy.next] method. /// /// Returns true if it successfully found a node and requested focus. - bool nextFocus() => FocusTraversalGroup.of(context!)!.next(this); + bool nextFocus() => FocusTraversalGroup.of(context!).next(this); /// Request to move the focus to the previous focus node, by calling the /// [FocusTraversalPolicy.previous] method. /// /// Returns true if it successfully found a node and requested focus. - bool previousFocus() => FocusTraversalGroup.of(context!)!.previous(this); + bool previousFocus() => FocusTraversalGroup.of(context!).previous(this); /// Request to move the focus to the nearest focus node in the given /// direction, by calling the [FocusTraversalPolicy.inDirection] method. /// /// Returns true if it successfully found a node and requested focus. - bool focusInDirection(TraversalDirection direction) => FocusTraversalGroup.of(context!)!.inDirection(this, direction); + bool focusInDirection(TraversalDirection direction) => FocusTraversalGroup.of(context!).inDirection(this, direction); @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { diff --git a/packages/flutter/lib/src/widgets/focus_scope.dart b/packages/flutter/lib/src/widgets/focus_scope.dart index b37d1c13574ad..a032088c63e93 100644 --- a/packages/flutter/lib/src/widgets/focus_scope.dart +++ b/packages/flutter/lib/src/widgets/focus_scope.dart @@ -433,21 +433,24 @@ class Focus extends StatefulWidget { /// /// If no [Focus] node is found before reaching the nearest [FocusScope] /// widget, or there is no [Focus] widget in scope, then this method will - /// throw an exception. To return null instead of throwing, pass true for - /// [nullOk]. + /// throw an exception. /// - /// The [context] and [nullOk] arguments must not be null. + /// The `context` and `scopeOk` arguments must not be null. /// /// Calling this function creates a dependency that will rebuild the given /// context when the focus changes. - static FocusNode? of(BuildContext context, { bool nullOk = false, bool scopeOk = false }) { + /// + /// See also: + /// + /// * [maybeOf], which is similar to this function, but will return null + /// instead of throwing if it doesn't find a [Focus] node. + static FocusNode of(BuildContext context, { bool scopeOk = false }) { assert(context != null); - assert(nullOk != null); assert(scopeOk != null); final _FocusMarker? marker = context.dependOnInheritedWidgetOfExactType<_FocusMarker>(); final FocusNode? node = marker?.notifier; - if (node == null) { - if (!nullOk) { + assert(() { + if (node == null) { throw FlutterError( 'Focus.of() was called with a context that does not contain a Focus widget.\n' 'No Focus widget ancestor could be found starting from the context that was passed to ' @@ -457,10 +460,10 @@ class Focus extends StatefulWidget { ' $context' ); } - return null; - } - if (!scopeOk && node is FocusScopeNode) { - if (!nullOk) { + return true; + }()); + assert(() { + if (!scopeOk && node is FocusScopeNode) { throw FlutterError( 'Focus.of() was called with a context that does not contain a Focus between the given ' 'context and the nearest FocusScope widget.\n' @@ -472,6 +475,36 @@ class Focus extends StatefulWidget { ' $context' ); } + return true; + }()); + return node!; + } + + /// Returns the [focusNode] of the [Focus] that most tightly encloses the + /// given [BuildContext]. + /// + /// If no [Focus] node is found before reaching the nearest [FocusScope] + /// widget, or there is no [Focus] widget in scope, then this method will + /// return null. + /// + /// The `context` and `scopeOk` arguments must not be null. + /// + /// Calling this function creates a dependency that will rebuild the given + /// context when the focus changes. + /// + /// See also: + /// + /// * [of], which is similar to this function, but will throw an exception if + /// it doesn't find a [Focus] node instead of returning null. + static FocusNode? maybeOf(BuildContext context, { bool scopeOk = false }) { + assert(context != null); + assert(scopeOk != null); + final _FocusMarker? marker = context.dependOnInheritedWidgetOfExactType<_FocusMarker>(); + final FocusNode? node = marker?.notifier; + if (node == null) { + return null; + } + if (!scopeOk && node is FocusScopeNode) { return null; } return node; @@ -489,7 +522,7 @@ class Focus extends StatefulWidget { /// /// Calling this function creates a dependency that will rebuild the given /// context when the focus changes. - static bool isAt(BuildContext context) => Focus.of(context, nullOk: true)?.hasFocus ?? false; + static bool isAt(BuildContext context) => Focus.maybeOf(context)?.hasFocus ?? false; @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { diff --git a/packages/flutter/lib/src/widgets/focus_traversal.dart b/packages/flutter/lib/src/widgets/focus_traversal.dart index 8ef0a195d5e72..596d89cc306ff 100644 --- a/packages/flutter/lib/src/widgets/focus_traversal.dart +++ b/packages/flutter/lib/src/widgets/focus_traversal.dart @@ -1363,7 +1363,7 @@ class OrderedTraversalPolicy extends FocusTraversalPolicy with DirectionalFocusT final List unordered = []; final List<_OrderedFocusInfo> ordered = <_OrderedFocusInfo>[]; for (final FocusNode node in sortedDescendants) { - final FocusOrder? order = FocusTraversalOrder.of(node.context!, nullOk: true); + final FocusOrder? order = FocusTraversalOrder.maybeOf(node.context!); if (order != null) { ordered.add(_OrderedFocusInfo(node: node, order: order)); } else { @@ -1393,30 +1393,49 @@ class OrderedTraversalPolicy extends FocusTraversalPolicy with DirectionalFocusT /// [FocusTraversalOrder.of] for a particular context. class FocusTraversalOrder extends InheritedWidget { /// A const constructor so that subclasses can be const. - const FocusTraversalOrder({Key? key, this.order, required Widget child}) : super(key: key, child: child); + const FocusTraversalOrder({Key? key, required this.order, required Widget child}) : super(key: key, child: child); /// The order for the widget descendants of this [FocusTraversalOrder]. - final FocusOrder? order; + final FocusOrder order; /// Finds the [FocusOrder] in the nearest ancestor [FocusTraversalOrder] widget. /// /// It does not create a rebuild dependency because changing the traversal /// order doesn't change the widget tree, so nothing needs to be rebuilt as a /// result of an order change. - static FocusOrder? of(BuildContext context, {bool nullOk = false}) { + /// + /// If no [FocusTraversalOrder] ancestor exists, or the order is null, this + /// will assert in debug mode, and throw an exception in release mode. + static FocusOrder of(BuildContext context) { assert(context != null); - assert(nullOk != null); final FocusTraversalOrder? marker = context.getElementForInheritedWidgetOfExactType()?.widget as FocusTraversalOrder?; - final FocusOrder? order = marker?.order; - if (order == null && !nullOk) { - throw FlutterError('FocusTraversalOrder.of() was called with a context that ' - 'does not contain a TraversalOrder widget. No TraversalOrder widget ' + assert((){ + if (marker == null) { + throw FlutterError( + 'FocusTraversalOrder.of() was called with a context that ' + 'does not contain a FocusTraversalOrder widget. No TraversalOrder widget ' 'ancestor could be found starting from the context that was passed to ' 'FocusTraversalOrder.of().\n' 'The context used was:\n' - ' $context'); - } - return order; + ' $context', + ); + } + return true; + }()); + return marker!.order; + } + + /// Finds the [FocusOrder] in the nearest ancestor [FocusTraversalOrder] widget. + /// + /// It does not create a rebuild dependency because changing the traversal + /// order doesn't change the widget tree, so nothing needs to be rebuilt as a + /// result of an order change. + /// + /// If no [FocusTraversalOrder] ancestor exists, or the order is null, returns null. + static FocusOrder? maybeOf(BuildContext context) { + assert(context != null); + final FocusTraversalOrder? marker = context.getElementForInheritedWidgetOfExactType()?.widget as FocusTraversalOrder?; + return marker?.order; } // Since the order of traversal doesn't affect display of anything, we don't @@ -1670,17 +1689,16 @@ class FocusTraversalGroup extends StatefulWidget { /// order doesn't change the widget tree, so nothing needs to be rebuilt as a /// result of an order change. /// - /// Will assert if no [FocusTraversalGroup] ancestor is found, and `nullOk` is false. + /// Will assert if no [FocusTraversalGroup] ancestor is found. /// - /// If `nullOk` is true, then it will return null if it doesn't find a - /// [FocusTraversalGroup] ancestor. - static FocusTraversalPolicy? of(BuildContext context, {bool nullOk = false}) { + /// See also: + /// + /// * [maybeOf] for a similar function that will return null if no + /// [FocusTraversalGroup] ancestor is found. + static FocusTraversalPolicy of(BuildContext context) { assert(context != null); final _FocusTraversalGroupMarker? inherited = context.dependOnInheritedWidgetOfExactType<_FocusTraversalGroupMarker>(); assert(() { - if (nullOk) { - return true; - } if (inherited == null) { throw FlutterError( 'Unable to find a FocusTraversalGroup widget in the context.\n' @@ -1696,6 +1714,25 @@ class FocusTraversalGroup extends StatefulWidget { } return true; }()); + return inherited!.policy; + } + + /// Returns the focus policy set by the [FocusTraversalGroup] that most + /// tightly encloses the given [BuildContext]. + /// + /// It does not create a rebuild dependency because changing the traversal + /// order doesn't change the widget tree, so nothing needs to be rebuilt as a + /// result of an order change. + /// + /// Will return null if it doesn't find a [FocusTraversalGroup] ancestor. + /// + /// See also: + /// + /// * [of] for a similar function that will throw if no [FocusTraversalGroup] + /// ancestor is found. + static FocusTraversalPolicy? maybeOf(BuildContext context) { + assert(context != null); + final _FocusTraversalGroupMarker? inherited = context.dependOnInheritedWidgetOfExactType<_FocusTraversalGroupMarker>(); return inherited?.policy; } diff --git a/packages/flutter/test/material/checkbox_list_tile_test.dart b/packages/flutter/test/material/checkbox_list_tile_test.dart index d22e3dfbb4f08..28429fdbea616 100644 --- a/packages/flutter/test/material/checkbox_list_tile_test.dart +++ b/packages/flutter/test/material/checkbox_list_tile_test.dart @@ -98,7 +98,7 @@ void main() { ); await tester.pump(); - expect(Focus.of(childKey.currentContext!, nullOk: true)!.hasPrimaryFocus, isTrue); + expect(Focus.maybeOf(childKey.currentContext!)!.hasPrimaryFocus, isTrue); await tester.pumpWidget( wrap( @@ -112,7 +112,7 @@ void main() { ); await tester.pump(); - expect(Focus.of(childKey.currentContext!, nullOk: true)!.hasPrimaryFocus, isFalse); + expect(Focus.maybeOf(childKey.currentContext!)!.hasPrimaryFocus, isFalse); }); testWidgets('CheckboxListTile contentPadding test', (WidgetTester tester) async { diff --git a/packages/flutter/test/material/dropdown_test.dart b/packages/flutter/test/material/dropdown_test.dart index 8151edbe04e43..7d77a1a623179 100644 --- a/packages/flutter/test/material/dropdown_test.dart +++ b/packages/flutter/test/material/dropdown_test.dart @@ -2328,7 +2328,7 @@ void main() { await tester.pump(); await tester.pump(const Duration(seconds: 1)); // finish the menu open animation expect(value, equals('one')); - expect(Focus.of(tester.element(find.byKey(const ValueKey('one')).last))!.hasPrimaryFocus, isTrue); + expect(Focus.of(tester.element(find.byKey(const ValueKey('one')).last)).hasPrimaryFocus, isTrue); await tester.sendKeyEvent(LogicalKeyboardKey.tab); // Focus 'two' await tester.pump(); @@ -2345,7 +2345,7 @@ void main() { await tester.pump(const Duration(seconds: 1)); // finish the menu open animation expect(value, equals('two')); final Element element = tester.element(find.byKey(const ValueKey('two')).last); - final FocusNode node = Focus.of(element)!; + final FocusNode node = Focus.of(element); expect(node.hasFocus, isTrue); }, skip: isBrowser); // https://github.com/flutter/flutter/issues/55320 @@ -2392,7 +2392,7 @@ void main() { await tester.pump(); await tester.pump(const Duration(seconds: 1)); // finish the menu open animation expect(value, equals(1)); - expect(Focus.of(tester.element(find.byKey(const ValueKey(1)).last))!.hasPrimaryFocus, isTrue); + expect(Focus.of(tester.element(find.byKey(const ValueKey(1)).last)).hasPrimaryFocus, isTrue); for (int i = 0; i < 41; ++i) { await tester.sendKeyEvent(LogicalKeyboardKey.tab); // Move to the next one. @@ -2408,7 +2408,7 @@ void main() { await tester.pump(const Duration(seconds: 1)); // finish the menu open animation expect(value, equals(42)); final Element element = tester.element(find.byKey(const ValueKey(42)).last); - final FocusNode node = Focus.of(element)!; + final FocusNode node = Focus.of(element); expect(node.hasFocus, isTrue); }, skip: isBrowser); // https://github.com/flutter/flutter/issues/55320 @@ -2454,14 +2454,14 @@ void main() { await tester.sendKeyEvent(LogicalKeyboardKey.enter); await tester.pumpAndSettle(); expect(value, equals(1)); - expect(Focus.of(tester.element(find.byKey(const ValueKey(1)).last))!.hasPrimaryFocus, isTrue); + expect(Focus.of(tester.element(find.byKey(const ValueKey(1)).last)).hasPrimaryFocus, isTrue); // Move to an item very far down the menu. for (int i = 0; i < 90; ++i) { await tester.sendKeyEvent(LogicalKeyboardKey.tab); // Move to the next one. await tester.pumpAndSettle(); // Wait for it to animate the menu. } - expect(Focus.of(tester.element(find.byKey(const ValueKey(91)).last))!.hasPrimaryFocus, isTrue); + expect(Focus.of(tester.element(find.byKey(const ValueKey(91)).last)).hasPrimaryFocus, isTrue); // Scroll back to the top using touch, and make sure we end up there. final Finder menu = find.byWidgetPredicate((Widget widget) { @@ -2483,7 +2483,7 @@ void main() { // Scrolling to the top again has removed the one the focus was on from the // tree, causing it to lose focus. - expect(Focus.of(tester.element(find.byKey(const ValueKey(91)).last))!.hasPrimaryFocus, isFalse); + expect(Focus.of(tester.element(find.byKey(const ValueKey(91)).last)).hasPrimaryFocus, isFalse); }, skip: isBrowser); // https://github.com/flutter/flutter/issues/55320 testWidgets('DropdownButton onTap callback is called when defined', (WidgetTester tester) async { diff --git a/packages/flutter/test/material/list_tile_test.dart b/packages/flutter/test/material/list_tile_test.dart index 4851ea12f5d30..a8fbcfffa2c28 100644 --- a/packages/flutter/test/material/list_tile_test.dart +++ b/packages/flutter/test/material/list_tile_test.dart @@ -1173,10 +1173,10 @@ void main() { ); await tester.pump(); // Let the focus take effect. - final FocusNode? tileNode = Focus.of(childKey.currentContext!); - tileNode!.requestFocus(); + final FocusNode tileNode = Focus.of(childKey.currentContext!); + tileNode.requestFocus(); await tester.pump(); // Let the focus take effect. - expect(Focus.of(childKey.currentContext!, nullOk: true)!.hasPrimaryFocus, isTrue); + expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isTrue); expect(tileNode.hasPrimaryFocus, isTrue); await tester.pumpWidget( @@ -1197,7 +1197,7 @@ void main() { ); expect(tester.binding.focusManager.primaryFocus, isNot(equals(tileNode))); - expect(Focus.of(childKey.currentContext!, nullOk: true)!.hasPrimaryFocus, isFalse); + expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isFalse); }); testWidgets('ListTile can autofocus unless disabled.', (WidgetTester tester) async { @@ -1222,7 +1222,7 @@ void main() { ); await tester.pump(); - expect(Focus.of(childKey.currentContext!, nullOk: true)!.hasPrimaryFocus, isTrue); + expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isTrue); await tester.pumpWidget( MaterialApp( @@ -1243,7 +1243,7 @@ void main() { ); await tester.pump(); - expect(Focus.of(childKey.currentContext!, nullOk: true)!.hasPrimaryFocus, isFalse); + expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isFalse); }); testWidgets('ListTile is focusable and has correct focus color', (WidgetTester tester) async { diff --git a/packages/flutter/test/material/popup_menu_test.dart b/packages/flutter/test/material/popup_menu_test.dart index 891b13f06876a..ec7bc25bb7520 100644 --- a/packages/flutter/test/material/popup_menu_test.dart +++ b/packages/flutter/test/material/popup_menu_test.dart @@ -189,7 +189,7 @@ void main() { await tester.pumpWidget(buildApp(directional: true)); // Try to bring up the popup menu and select the first item from it - Focus.of(popupButtonKey.currentContext!)!.requestFocus(); + Focus.of(popupButtonKey.currentContext!).requestFocus(); await tester.pumpAndSettle(); await tester.tap(find.byKey(popupButtonKey)); await tester.pumpAndSettle(); @@ -238,10 +238,10 @@ void main() { ), ), ); - Focus.of(childKey.currentContext!)!.requestFocus(); + Focus.of(childKey.currentContext!).requestFocus(); await tester.pump(); - expect(Focus.of(childKey.currentContext!)!.hasPrimaryFocus, isFalse); + expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isFalse); expect(itemBuilderCalled, isFalse); expect(onSelectedCalled, isFalse); }); @@ -281,10 +281,10 @@ void main() { }), ), ); - Focus.of(childKey.currentContext!)!.requestFocus(); + Focus.of(childKey.currentContext!).requestFocus(); await tester.pump(); - expect(Focus.of(childKey.currentContext!)!.hasPrimaryFocus, isTrue); + expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isTrue); }); testWidgets('PopupMenuItem is only focusable when enabled', (WidgetTester tester) async { @@ -319,7 +319,7 @@ void main() { // Open the popup to build and show the menu contents. await tester.tap(find.byKey(popupButtonKey)); await tester.pumpAndSettle(); - final FocusNode childNode = Focus.of(childKey.currentContext!)!; + final FocusNode childNode = Focus.of(childKey.currentContext!); // Now that the contents are shown, request focus on the child text. childNode.requestFocus(); await tester.pumpAndSettle(); @@ -362,7 +362,7 @@ void main() { await tester.pumpAndSettle(); expect(itemBuilderCalled, isTrue); - expect(Focus.of(childKey.currentContext!)!.hasPrimaryFocus, isFalse); + expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isFalse); }); testWidgets('PopupMenuButton is horizontal on iOS', (WidgetTester tester) async { diff --git a/packages/flutter/test/material/radio_list_tile_test.dart b/packages/flutter/test/material/radio_list_tile_test.dart index 8f0742bc07ba1..98d4fefa30cac 100644 --- a/packages/flutter/test/material/radio_list_tile_test.dart +++ b/packages/flutter/test/material/radio_list_tile_test.dart @@ -589,7 +589,7 @@ void main() { ); await tester.pump(); - expect(Focus.of(childKey.currentContext!)!.hasPrimaryFocus, isTrue); + expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isTrue); await tester.pumpWidget( wrap( @@ -604,7 +604,7 @@ void main() { ); await tester.pump(); - expect(Focus.of(childKey.currentContext!)!.hasPrimaryFocus, isFalse); + expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isFalse); }); testWidgets('RadioListTile contentPadding test', (WidgetTester tester) async { diff --git a/packages/flutter/test/material/stepper_test.dart b/packages/flutter/test/material/stepper_test.dart index bbc1becae860e..4de65f56eb608 100644 --- a/packages/flutter/test/material/stepper_test.dart +++ b/packages/flutter/test/material/stepper_test.dart @@ -624,7 +624,7 @@ void main() { ); await tester.pump(); - final FocusNode disabledNode = Focus.of(tester.element(find.text('Step 0')), nullOk: true, scopeOk: true)!; + final FocusNode disabledNode = Focus.of(tester.element(find.text('Step 0')), scopeOk: true); disabledNode.requestFocus(); await tester.pump(); expect(disabledNode.hasPrimaryFocus, isFalse); @@ -650,7 +650,7 @@ void main() { ); await tester.pump(); - final FocusNode disabledNode = Focus.of(tester.element(find.text('Step 0')), nullOk: true, scopeOk: true)!; + final FocusNode disabledNode = Focus.of(tester.element(find.text('Step 0')), scopeOk: true); disabledNode.requestFocus(); await tester.pump(); expect(disabledNode.hasPrimaryFocus, isFalse); diff --git a/packages/flutter/test/material/switch_list_tile_test.dart b/packages/flutter/test/material/switch_list_tile_test.dart index f40c7cf49ac20..4c7a3c075a600 100644 --- a/packages/flutter/test/material/switch_list_tile_test.dart +++ b/packages/flutter/test/material/switch_list_tile_test.dart @@ -276,7 +276,7 @@ void main() { ); await tester.pump(); - expect(Focus.of(childKey.currentContext!)!.hasPrimaryFocus, isTrue); + expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isTrue); await tester.pumpWidget( MaterialApp( @@ -296,7 +296,7 @@ void main() { ); await tester.pump(); - expect(Focus.of(childKey.currentContext!)!.hasPrimaryFocus, isFalse); + expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isFalse); }); testWidgets('SwitchListTile controlAffinity test', (WidgetTester tester) async { diff --git a/packages/flutter/test/widgets/editable_text_test.dart b/packages/flutter/test/widgets/editable_text_test.dart index f7ed48f44077e..74518774e751d 100644 --- a/packages/flutter/test/widgets/editable_text_test.dart +++ b/packages/flutter/test/widgets/editable_text_test.dart @@ -1597,8 +1597,8 @@ void main() { await tester.testTextInput.receiveAction(action); await tester.pump(); - expect(Focus.of(nextKey.currentContext!)!.hasFocus, equals(shouldFocusNext)); - expect(Focus.of(previousKey.currentContext!)!.hasFocus, equals(shouldFocusPrevious)); + expect(Focus.of(nextKey.currentContext!).hasFocus, equals(shouldFocusNext)); + expect(Focus.of(previousKey.currentContext!).hasFocus, equals(shouldFocusPrevious)); expect(focusNode.hasFocus, equals(!shouldLoseFocus)); } diff --git a/packages/flutter/test/widgets/focus_scope_test.dart b/packages/flutter/test/widgets/focus_scope_test.dart index aa59478323727..a02c692d8ddab 100644 --- a/packages/flutter/test/widgets/focus_scope_test.dart +++ b/packages/flutter/test/widgets/focus_scope_test.dart @@ -1117,12 +1117,12 @@ void main() { final Element element6 = tester.element(find.byKey(key6)); final FocusNode root = element1.owner!.focusManager.rootScope; - expect(Focus.of(element1, nullOk: true), isNull); - expect(Focus.of(element2, nullOk: true), isNull); - expect(Focus.of(element3, nullOk: true), isNull); - expect(Focus.of(element4)!.parent!.parent, equals(root)); - expect(Focus.of(element5)!.parent!.parent, equals(root)); - expect(Focus.of(element6)!.parent!.parent!.parent, equals(root)); + expect(Focus.maybeOf(element1), isNull); + expect(Focus.maybeOf(element2), isNull); + expect(Focus.maybeOf(element3), isNull); + expect(Focus.of(element4).parent!.parent, equals(root)); + expect(Focus.of(element5).parent!.parent, equals(root)); + expect(Focus.of(element6).parent!.parent!.parent, equals(root)); }); testWidgets('Can traverse Focus children.', (WidgetTester tester) async { final GlobalKey key1 = GlobalKey(debugLabel: '1'); @@ -1187,7 +1187,7 @@ void main() { await tester.pump(); - Focus.of(firstScope)!.descendants.forEach(visitor); + Focus.of(firstScope).descendants.forEach(visitor); expect(nodes.length, equals(7)); expect(keys.length, equals(7)); // Depth first. @@ -1197,7 +1197,7 @@ void main() { final Element secondScope = tester.element(find.byKey(key7)); nodes.clear(); keys.clear(); - Focus.of(secondScope)!.descendants.forEach(visitor); + Focus.of(secondScope).descendants.forEach(visitor); expect(nodes.length, equals(2)); expect(keys, equals([key7, key8])); }); @@ -1213,7 +1213,7 @@ void main() { ); final Element firstNode = tester.element(find.byKey(key1)); - final FocusNode node = Focus.of(firstNode)!; + final FocusNode node = Focus.of(firstNode); node.requestFocus(); await tester.pump(); @@ -1234,7 +1234,7 @@ void main() { ); final Element firstNode = tester.element(find.byKey(key1)); - final FocusNode node = Focus.of(firstNode)!; + final FocusNode node = Focus.of(firstNode); node.requestFocus(); await tester.pump(); @@ -1256,7 +1256,7 @@ void main() { ); Element firstNode = tester.element(find.byKey(key1)); - FocusNode node = Focus.of(firstNode)!; + FocusNode node = Focus.of(firstNode); node.requestFocus(); await tester.pump(); @@ -1274,7 +1274,7 @@ void main() { ); firstNode = tester.element(find.byKey(key1)); - node = Focus.of(firstNode)!; + node = Focus.of(firstNode); node.requestFocus(); await tester.pump(); @@ -1297,7 +1297,7 @@ void main() { ); final Element childWidget = tester.element(find.byKey(key1)); - final FocusNode unfocusableNode = Focus.of(childWidget)!; + final FocusNode unfocusableNode = Focus.of(childWidget); unfocusableNode.requestFocus(); await tester.pump(); @@ -1306,7 +1306,7 @@ void main() { expect(unfocusableNode.hasFocus, isFalse); final Element containerWidget = tester.element(find.byKey(key2)); - final FocusNode focusableNode = Focus.of(containerWidget)!; + final FocusNode focusableNode = Focus.of(containerWidget); focusableNode.requestFocus(); await tester.pump(); @@ -1328,7 +1328,7 @@ void main() { ); final Element firstNode = tester.element(find.byKey(key1)); - final FocusNode node = Focus.of(firstNode)!; + final FocusNode node = Focus.of(firstNode); node.requestFocus(); await tester.pump(); @@ -1425,75 +1425,75 @@ void main() { // Check childless node (focus2). await pumpTest(); - Focus.of(container1.currentContext!)!.requestFocus(); + Focus.of(container1.currentContext!).requestFocus(); await tester.pump(); - expect(Focus.of(container1.currentContext!)!.hasFocus, isTrue); + expect(Focus.of(container1.currentContext!).hasFocus, isTrue); await pumpTest(allowFocus2: false); - expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); - Focus.of(container1.currentContext!)!.requestFocus(); + expect(Focus.of(container1.currentContext!).hasFocus, isFalse); + Focus.of(container1.currentContext!).requestFocus(); await tester.pump(); - expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); + expect(Focus.of(container1.currentContext!).hasFocus, isFalse); await pumpTest(); - Focus.of(container1.currentContext!)!.requestFocus(); + Focus.of(container1.currentContext!).requestFocus(); await tester.pump(); - expect(Focus.of(container1.currentContext!)!.hasFocus, isTrue); + expect(Focus.of(container1.currentContext!).hasFocus, isTrue); // Check FocusNode with child (focus1). Shouldn't affect children. await pumpTest(allowFocus1: false); - expect(Focus.of(container1.currentContext!)!.hasFocus, isTrue); // focus2 has focus. - Focus.of(focus2.currentContext!)!.requestFocus(); // Try to focus focus1 + expect(Focus.of(container1.currentContext!).hasFocus, isTrue); // focus2 has focus. + Focus.of(focus2.currentContext!).requestFocus(); // Try to focus focus1 await tester.pump(); - expect(Focus.of(container1.currentContext!)!.hasFocus, isTrue); // focus2 still has focus. - Focus.of(container1.currentContext!)!.requestFocus(); // Now try to focus focus2 + expect(Focus.of(container1.currentContext!).hasFocus, isTrue); // focus2 still has focus. + Focus.of(container1.currentContext!).requestFocus(); // Now try to focus focus2 await tester.pump(); - expect(Focus.of(container1.currentContext!)!.hasFocus, isTrue); + expect(Focus.of(container1.currentContext!).hasFocus, isTrue); await pumpTest(); // Try again, now that we've set focus1's canRequestFocus to true again. - Focus.of(container1.currentContext!)!.unfocus(); + Focus.of(container1.currentContext!).unfocus(); await tester.pump(); - expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); - Focus.of(container1.currentContext!)!.requestFocus(); + expect(Focus.of(container1.currentContext!).hasFocus, isFalse); + Focus.of(container1.currentContext!).requestFocus(); await tester.pump(); - expect(Focus.of(container1.currentContext!)!.hasFocus, isTrue); + expect(Focus.of(container1.currentContext!).hasFocus, isTrue); // Check FocusScopeNode with only FocusNode children (scope2). Should affect children. await pumpTest(allowScope2: false); - expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); + expect(Focus.of(container1.currentContext!).hasFocus, isFalse); FocusScope.of(focus1.currentContext!).requestFocus(); // Try to focus scope2 await tester.pump(); - expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); - Focus.of(focus2.currentContext!)!.requestFocus(); // Try to focus focus1 + expect(Focus.of(container1.currentContext!).hasFocus, isFalse); + Focus.of(focus2.currentContext!).requestFocus(); // Try to focus focus1 await tester.pump(); - expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); - Focus.of(container1.currentContext!)!.requestFocus(); // Try to focus focus2 + expect(Focus.of(container1.currentContext!).hasFocus, isFalse); + Focus.of(container1.currentContext!).requestFocus(); // Try to focus focus2 await tester.pump(); - expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); + expect(Focus.of(container1.currentContext!).hasFocus, isFalse); await pumpTest(); // Try again, now that we've set scope2's canRequestFocus to true again. - Focus.of(container1.currentContext!)!.requestFocus(); + Focus.of(container1.currentContext!).requestFocus(); await tester.pump(); - expect(Focus.of(container1.currentContext!)!.hasFocus, isTrue); + expect(Focus.of(container1.currentContext!).hasFocus, isTrue); // Check FocusScopeNode with both FocusNode children and FocusScope children (scope1). Should affect children. await pumpTest(allowScope1: false); - expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); + expect(Focus.of(container1.currentContext!).hasFocus, isFalse); FocusScope.of(scope2.currentContext!).requestFocus(); // Try to focus scope1 await tester.pump(); - expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); + expect(Focus.of(container1.currentContext!).hasFocus, isFalse); FocusScope.of(focus1.currentContext!).requestFocus(); // Try to focus scope2 await tester.pump(); - expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); - Focus.of(focus2.currentContext!)!.requestFocus(); // Try to focus focus1 + expect(Focus.of(container1.currentContext!).hasFocus, isFalse); + Focus.of(focus2.currentContext!).requestFocus(); // Try to focus focus1 await tester.pump(); - expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); - Focus.of(container1.currentContext!)!.requestFocus(); // Try to focus focus2 + expect(Focus.of(container1.currentContext!).hasFocus, isFalse); + Focus.of(container1.currentContext!).requestFocus(); // Try to focus focus2 await tester.pump(); - expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); + expect(Focus.of(container1.currentContext!).hasFocus, isFalse); await pumpTest(); // Try again, now that we've set scope1's canRequestFocus to true again. - Focus.of(container1.currentContext!)!.requestFocus(); + Focus.of(container1.currentContext!).requestFocus(); await tester.pump(); - expect(Focus.of(container1.currentContext!)!.hasFocus, isTrue); + expect(Focus.of(container1.currentContext!).hasFocus, isTrue); }); testWidgets('skipTraversal works as expected.', (WidgetTester tester) async { @@ -1569,9 +1569,9 @@ void main() { ); final Element childWidget = tester.element(find.byKey(key1)); - final FocusNode unfocusableNode = Focus.of(childWidget)!; + final FocusNode unfocusableNode = Focus.of(childWidget); final Element containerWidget = tester.element(find.byKey(key2)); - final FocusNode containerNode = Focus.of(containerWidget)!; + final FocusNode containerNode = Focus.of(containerWidget); unfocusableNode.requestFocus(); await tester.pump(); @@ -1615,9 +1615,9 @@ void main() { ); final Element childWidget = tester.element(find.byKey(key1)); - final FocusNode unfocusableNode = Focus.of(childWidget)!; + final FocusNode unfocusableNode = Focus.of(childWidget); final Element containerWidget = tester.element(find.byKey(key2)); - final FocusNode containerNode = Focus.of(containerWidget)!; + final FocusNode containerNode = Focus.of(containerWidget); unfocusableNode.requestFocus(); await tester.pump(); diff --git a/packages/flutter/test/widgets/focus_traversal_test.dart b/packages/flutter/test/widgets/focus_traversal_test.dart index b540c4f65dc03..24a686fa872b0 100644 --- a/packages/flutter/test/widgets/focus_traversal_test.dart +++ b/packages/flutter/test/widgets/focus_traversal_test.dart @@ -53,9 +53,9 @@ void main() { final Element firstChild = tester.element(find.byKey(key3)); final Element secondChild = tester.element(find.byKey(key5)); - final FocusNode firstFocusNode = Focus.of(firstChild)!; - final FocusNode secondFocusNode = Focus.of(secondChild)!; - final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; + final FocusNode firstFocusNode = Focus.of(firstChild); + final FocusNode secondFocusNode = Focus.of(secondChild); + final FocusNode scope = Focus.of(firstChild).enclosingScope!; secondFocusNode.nextFocus(); await tester.pump(); @@ -92,9 +92,9 @@ void main() { final Element firstChild = tester.element(find.byKey(key3)); final Element secondChild = tester.element(find.byKey(key5)); - final FocusNode firstFocusNode = Focus.of(firstChild)!; - final FocusNode secondFocusNode = Focus.of(secondChild)!; - final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; + final FocusNode firstFocusNode = Focus.of(firstChild); + final FocusNode secondFocusNode = Focus.of(secondChild); + final FocusNode scope = Focus.of(firstChild).enclosingScope!; expect(firstFocusNode.hasFocus, isFalse); expect(secondFocusNode.hasFocus, isFalse); @@ -157,9 +157,9 @@ void main() { final Element firstChild = tester.element(find.byKey(key4)); final Element secondChild = tester.element(find.byKey(key6)); - final FocusNode firstFocusNode = Focus.of(firstChild)!; - final FocusNode secondFocusNode = Focus.of(secondChild)!; - final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; + final FocusNode firstFocusNode = Focus.of(firstChild); + final FocusNode secondFocusNode = Focus.of(secondChild); + final FocusNode scope = Focus.of(firstChild).enclosingScope!; firstFocusNode.requestFocus(); await tester.pump(); @@ -177,7 +177,7 @@ void main() { focus3 = null; focus5 = null; - Focus.of(firstChild)!.nextFocus(); + Focus.of(firstChild).nextFocus(); await tester.pump(); @@ -194,7 +194,7 @@ void main() { focus3 = null; focus5 = null; - Focus.of(firstChild)!.nextFocus(); + Focus.of(firstChild).nextFocus(); await tester.pump(); @@ -212,7 +212,7 @@ void main() { focus5 = null; // Tests that can still move back to original node. - Focus.of(firstChild)!.previousFocus(); + Focus.of(firstChild).previousFocus(); await tester.pump(); @@ -262,9 +262,9 @@ void main() { final Element firstChild = tester.element(find.byKey(key4)); final Element secondChild = tester.element(find.byKey(key6)); - final FocusNode firstFocusNode = Focus.of(firstChild)!; - final FocusNode secondFocusNode = Focus.of(secondChild)!; - final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; + final FocusNode firstFocusNode = Focus.of(firstChild); + final FocusNode secondFocusNode = Focus.of(secondChild); + final FocusNode scope = Focus.of(firstChild).enclosingScope!; secondFocusNode.requestFocus(); await tester.pump(); @@ -273,7 +273,7 @@ void main() { expect(secondFocusNode.hasFocus, isTrue); expect(scope.hasFocus, isTrue); - Focus.of(firstChild)!.previousFocus(); + Focus.of(firstChild).previousFocus(); await tester.pump(); @@ -281,7 +281,7 @@ void main() { expect(secondFocusNode.hasFocus, isFalse); expect(scope.hasFocus, isTrue); - Focus.of(firstChild)!.previousFocus(); + Focus.of(firstChild).previousFocus(); await tester.pump(); @@ -290,7 +290,7 @@ void main() { expect(scope.hasFocus, isTrue); // Tests that can still move back to original node. - Focus.of(firstChild)!.nextFocus(); + Focus.of(firstChild).nextFocus(); await tester.pump(); @@ -376,8 +376,8 @@ void main() { ); final Element firstChild = tester.element(find.text('Go Forward')); - final FocusNode firstFocusNode = Focus.of(firstChild)!; - final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; + final FocusNode firstFocusNode = Focus.of(firstChild); + final FocusNode scope = Focus.of(firstChild).enclosingScope!; await tester.pump(); expect(firstFocusNode.hasFocus, isTrue); @@ -387,7 +387,7 @@ void main() { await tester.pumpAndSettle(); final Element secondChild = tester.element(find.text('Go Back')); - final FocusNode secondFocusNode = Focus.of(secondChild)!; + final FocusNode secondFocusNode = Focus.of(secondChild); expect(firstFocusNode.hasFocus, isFalse); expect(secondFocusNode.hasFocus, isTrue); @@ -428,9 +428,9 @@ void main() { final Element firstChild = tester.element(find.byKey(key3)); final Element secondChild = tester.element(find.byKey(key5)); - final FocusNode firstFocusNode = Focus.of(firstChild)!; - final FocusNode secondFocusNode = Focus.of(secondChild)!; - final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; + final FocusNode firstFocusNode = Focus.of(firstChild); + final FocusNode secondFocusNode = Focus.of(secondChild); + final FocusNode scope = Focus.of(firstChild).enclosingScope!; secondFocusNode.nextFocus(); await tester.pump(); @@ -499,9 +499,9 @@ void main() { final Element firstChild = tester.element(find.byKey(key4)); final Element secondChild = tester.element(find.byKey(key6)); - final FocusNode firstFocusNode = Focus.of(firstChild)!; - final FocusNode secondFocusNode = Focus.of(secondChild)!; - final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; + final FocusNode firstFocusNode = Focus.of(firstChild); + final FocusNode secondFocusNode = Focus.of(secondChild); + final FocusNode scope = Focus.of(firstChild).enclosingScope!; firstFocusNode.requestFocus(); await tester.pump(); @@ -515,7 +515,7 @@ void main() { expect(scope.hasFocus, isTrue); clear(); - Focus.of(firstChild)!.nextFocus(); + Focus.of(firstChild).nextFocus(); await tester.pump(); @@ -528,7 +528,7 @@ void main() { expect(scope.hasFocus, isTrue); clear(); - Focus.of(firstChild)!.nextFocus(); + Focus.of(firstChild).nextFocus(); await tester.pump(); @@ -542,7 +542,7 @@ void main() { clear(); // Tests that can still move back to original node. - Focus.of(firstChild)!.previousFocus(); + Focus.of(firstChild).previousFocus(); await tester.pump(); @@ -592,9 +592,9 @@ void main() { final Element firstChild = tester.element(find.byKey(key4)); final Element secondChild = tester.element(find.byKey(key6)); - final FocusNode firstFocusNode = Focus.of(firstChild)!; - final FocusNode secondFocusNode = Focus.of(secondChild)!; - final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; + final FocusNode firstFocusNode = Focus.of(firstChild); + final FocusNode secondFocusNode = Focus.of(secondChild); + final FocusNode scope = Focus.of(firstChild).enclosingScope!; secondFocusNode.requestFocus(); await tester.pump(); @@ -603,7 +603,7 @@ void main() { expect(secondFocusNode.hasFocus, isTrue); expect(scope.hasFocus, isTrue); - Focus.of(firstChild)!.previousFocus(); + Focus.of(firstChild).previousFocus(); await tester.pump(); @@ -611,7 +611,7 @@ void main() { expect(secondFocusNode.hasFocus, isFalse); expect(scope.hasFocus, isTrue); - Focus.of(firstChild)!.previousFocus(); + Focus.of(firstChild).previousFocus(); await tester.pump(); @@ -620,7 +620,7 @@ void main() { expect(scope.hasFocus, isTrue); // Tests that can still move back to original node. - Focus.of(firstChild)!.nextFocus(); + Focus.of(firstChild).nextFocus(); await tester.pump(); @@ -867,9 +867,9 @@ void main() { final Element firstChild = tester.element(find.byKey(key1)); final Element secondChild = tester.element(find.byKey(key2)); - final FocusNode firstFocusNode = Focus.of(firstChild)!; - final FocusNode secondFocusNode = Focus.of(secondChild)!; - final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; + final FocusNode firstFocusNode = Focus.of(firstChild); + final FocusNode secondFocusNode = Focus.of(secondChild); + final FocusNode scope = Focus.of(firstChild).enclosingScope!; secondFocusNode.nextFocus(); await tester.pump(); @@ -1179,8 +1179,8 @@ void main() { ); final Element firstChild = tester.element(find.text('Go Forward')); - final FocusNode firstFocusNode = Focus.of(firstChild)!; - final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; + final FocusNode firstFocusNode = Focus.of(firstChild); + final FocusNode scope = Focus.of(firstChild).enclosingScope!; await tester.pump(); expect(firstFocusNode.hasFocus, isTrue); @@ -1190,7 +1190,7 @@ void main() { await tester.pumpAndSettle(); final Element secondChild = tester.element(find.text('Go Back')); - final FocusNode secondFocusNode = Focus.of(secondChild)!; + final FocusNode secondFocusNode = Focus.of(secondChild); expect(firstFocusNode.hasFocus, isFalse); expect(secondFocusNode.hasFocus, isTrue); @@ -1264,10 +1264,10 @@ void main() { focusLowerRight = null; } - final FocusNode upperLeftNode = Focus.of(tester.element(find.byKey(upperLeftKey)))!; - final FocusNode upperRightNode = Focus.of(tester.element(find.byKey(upperRightKey)))!; - final FocusNode lowerLeftNode = Focus.of(tester.element(find.byKey(lowerLeftKey)))!; - final FocusNode lowerRightNode = Focus.of(tester.element(find.byKey(lowerRightKey)))!; + final FocusNode upperLeftNode = Focus.of(tester.element(find.byKey(upperLeftKey))); + final FocusNode upperRightNode = Focus.of(tester.element(find.byKey(upperRightKey))); + final FocusNode lowerLeftNode = Focus.of(tester.element(find.byKey(lowerLeftKey))); + final FocusNode lowerRightNode = Focus.of(tester.element(find.byKey(lowerRightKey))); final FocusNode scope = upperLeftNode.enclosingScope!; upperLeftNode.requestFocus(); @@ -1408,7 +1408,7 @@ void main() { focus = List.generate(keys.length, (int _) => null); } - final List nodes = keys.map((GlobalKey key) => Focus.of(tester.element(find.byKey(key)))!).toList(); + final List nodes = keys.map((GlobalKey key) => Focus.of(tester.element(find.byKey(key)))).toList(); final FocusNode scope = nodes[0].enclosingScope!; nodes[4].requestFocus(); @@ -1527,14 +1527,14 @@ void main() { ), ); - final FocusNode upperLeftNode = Focus.of(tester.element(find.byKey(upperLeftKey)))!; - final FocusNode upperRightNode = Focus.of(tester.element(find.byKey(upperRightKey)))!; - final FocusNode lowerLeftNode = Focus.of(tester.element(find.byKey(lowerLeftKey)))!; + final FocusNode upperLeftNode = Focus.of(tester.element(find.byKey(upperLeftKey))); + final FocusNode upperRightNode = Focus.of(tester.element(find.byKey(upperRightKey))); + final FocusNode lowerLeftNode = Focus.of(tester.element(find.byKey(lowerLeftKey))); final FocusNode scope = upperLeftNode.enclosingScope!; await tester.pump(); - final FocusTraversalPolicy policy = FocusTraversalGroup.of(upperLeftKey.currentContext!)!; + final FocusTraversalPolicy policy = FocusTraversalGroup.of(upperLeftKey.currentContext!); expect(policy.findFirstFocusInDirection(scope, TraversalDirection.up), equals(lowerLeftNode)); expect(policy.findFirstFocusInDirection(scope, TraversalDirection.down), equals(upperLeftNode)); @@ -1644,42 +1644,42 @@ void main() { ), ); - expect(Focus.of(upperLeftKey.currentContext!)!.hasPrimaryFocus, isTrue); + expect(Focus.of(upperLeftKey.currentContext!).hasPrimaryFocus, isTrue); await tester.sendKeyEvent(LogicalKeyboardKey.tab); - expect(Focus.of(upperRightKey.currentContext!)!.hasPrimaryFocus, isTrue); + expect(Focus.of(upperRightKey.currentContext!).hasPrimaryFocus, isTrue); await tester.sendKeyEvent(LogicalKeyboardKey.tab); - expect(Focus.of(lowerLeftKey.currentContext!)!.hasPrimaryFocus, isTrue); + expect(Focus.of(lowerLeftKey.currentContext!).hasPrimaryFocus, isTrue); await tester.sendKeyEvent(LogicalKeyboardKey.tab); - expect(Focus.of(lowerRightKey.currentContext!)!.hasPrimaryFocus, isTrue); + expect(Focus.of(lowerRightKey.currentContext!).hasPrimaryFocus, isTrue); await tester.sendKeyEvent(LogicalKeyboardKey.tab); - expect(Focus.of(upperLeftKey.currentContext!)!.hasPrimaryFocus, isTrue); + expect(Focus.of(upperLeftKey.currentContext!).hasPrimaryFocus, isTrue); await tester.sendKeyDownEvent(LogicalKeyboardKey.shift); await tester.sendKeyEvent(LogicalKeyboardKey.tab); await tester.sendKeyUpEvent(LogicalKeyboardKey.shift); - expect(Focus.of(lowerRightKey.currentContext!)!.hasPrimaryFocus, isTrue); + expect(Focus.of(lowerRightKey.currentContext!).hasPrimaryFocus, isTrue); await tester.sendKeyDownEvent(LogicalKeyboardKey.shift); await tester.sendKeyEvent(LogicalKeyboardKey.tab); await tester.sendKeyUpEvent(LogicalKeyboardKey.shift); - expect(Focus.of(lowerLeftKey.currentContext!)!.hasPrimaryFocus, isTrue); + expect(Focus.of(lowerLeftKey.currentContext!).hasPrimaryFocus, isTrue); await tester.sendKeyDownEvent(LogicalKeyboardKey.shift); await tester.sendKeyEvent(LogicalKeyboardKey.tab); await tester.sendKeyUpEvent(LogicalKeyboardKey.shift); - expect(Focus.of(upperRightKey.currentContext!)!.hasPrimaryFocus, isTrue); + expect(Focus.of(upperRightKey.currentContext!).hasPrimaryFocus, isTrue); await tester.sendKeyDownEvent(LogicalKeyboardKey.shift); await tester.sendKeyEvent(LogicalKeyboardKey.tab); await tester.sendKeyUpEvent(LogicalKeyboardKey.shift); - expect(Focus.of(upperLeftKey.currentContext!)!.hasPrimaryFocus, isTrue); + expect(Focus.of(upperLeftKey.currentContext!).hasPrimaryFocus, isTrue); // Traverse in a direction await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight); - expect(Focus.of(upperRightKey.currentContext!)!.hasPrimaryFocus, isTrue); + expect(Focus.of(upperRightKey.currentContext!).hasPrimaryFocus, isTrue); await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown); - expect(Focus.of(lowerRightKey.currentContext!)!.hasPrimaryFocus, isTrue); + expect(Focus.of(lowerRightKey.currentContext!).hasPrimaryFocus, isTrue); await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft); - expect(Focus.of(lowerLeftKey.currentContext!)!.hasPrimaryFocus, isTrue); + expect(Focus.of(lowerLeftKey.currentContext!).hasPrimaryFocus, isTrue); await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp); - expect(Focus.of(upperLeftKey.currentContext!)!.hasPrimaryFocus, isTrue); + expect(Focus.of(upperLeftKey.currentContext!).hasPrimaryFocus, isTrue); }, skip: isBrowser); // https://github.com/flutter/flutter/issues/35347 testWidgets('Focus traversal inside a vertical scrollable scrolls to stay visible.', (WidgetTester tester) async { @@ -2070,9 +2070,9 @@ void main() { ); final Element childWidget = tester.element(find.byKey(key1)); - final FocusNode unfocusableNode = Focus.of(childWidget)!; + final FocusNode unfocusableNode = Focus.of(childWidget); final Element containerWidget = tester.element(find.byKey(key2)); - final FocusNode containerNode = Focus.of(containerWidget)!; + final FocusNode containerNode = Focus.of(containerWidget); unfocusableNode.requestFocus(); await tester.pump(); diff --git a/packages/flutter/test/widgets/platform_view_test.dart b/packages/flutter/test/widgets/platform_view_test.dart index 988a260cefbd2..4d38a5813ed6b 100644 --- a/packages/flutter/test/widgets/platform_view_test.dart +++ b/packages/flutter/test/widgets/platform_view_test.dart @@ -991,7 +991,7 @@ void main() { ); final Element containerElement = tester.element(find.byKey(containerKey)); final FocusNode androidViewFocusNode = androidViewFocusWidget.focusNode!; - final FocusNode containerFocusNode = Focus.of(containerElement)!; + final FocusNode containerFocusNode = Focus.of(containerElement); containerFocusNode.requestFocus(); @@ -1038,7 +1038,7 @@ void main() { final Element containerElement = tester.element(find.byKey(containerKey)); - final FocusNode containerFocusNode = Focus.of(containerElement)!; + final FocusNode containerFocusNode = Focus.of(containerElement); containerFocusNode.requestFocus(); await tester.pump(); @@ -1086,7 +1086,7 @@ void main() { viewsController.createCompleter!.complete(); final Element containerElement = tester.element(find.byKey(containerKey)); - final FocusNode containerFocusNode = Focus.of(containerElement)!; + final FocusNode containerFocusNode = Focus.of(containerElement); containerFocusNode.requestFocus(); await tester.pump(); @@ -2491,7 +2491,7 @@ void main() { ); final FocusNode platformViewFocusNode = platformViewFocusWidget.focusNode!; final Element containerElement = tester.element(find.byKey(containerKey)); - final FocusNode containerFocusNode = Focus.of(containerElement)!; + final FocusNode containerFocusNode = Focus.of(containerElement); containerFocusNode.requestFocus(); await tester.pump();