Unverified Commit fa3d2e21 authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Remove nullOk parameter from Focus.of, FocusTraversalOrder.of, and FocusTraversalGroup.of (#68917)

This removes the nullOk parameter from Focus.of, FocusTraversalOrder.of and FocusTraversalGroup.of, and creates maybeOf equivalents for each. The of methods now return non-nullable values, and the maybeOf equivalents return nullable values.
parent 4fa5fe5f
...@@ -1513,7 +1513,7 @@ class DropdownButtonFormField<T> extends FormField<T> { ...@@ -1513,7 +1513,7 @@ class DropdownButtonFormField<T> extends FormField<T> {
return InputDecorator( return InputDecorator(
decoration: effectiveDecoration.copyWith(errorText: field.errorText), decoration: effectiveDecoration.copyWith(errorText: field.errorText),
isEmpty: state.value == null, isEmpty: state.value == null,
isFocused: Focus.of(context)!.hasFocus, isFocused: Focus.of(context).hasFocus,
child: DropdownButtonHideUnderline( child: DropdownButtonHideUnderline(
child: DropdownButton<T>( child: DropdownButton<T>(
items: items, items: items,
......
...@@ -143,7 +143,7 @@ class FocusAttachment { ...@@ -143,7 +143,7 @@ class FocusAttachment {
assert(_node != null); assert(_node != null);
if (isAttached) { if (isAttached) {
assert(_node.context != null); 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; parent ??= _node.context!.owner!.focusManager.rootScope;
assert(parent != null); assert(parent != null);
parent._reparent(_node); parent._reparent(_node);
...@@ -1005,7 +1005,7 @@ class FocusNode with DiagnosticableTreeMixin, ChangeNotifier { ...@@ -1005,7 +1005,7 @@ class FocusNode with DiagnosticableTreeMixin, ChangeNotifier {
_manager?.primaryFocus?._setAsFocusedChildForScope(); _manager?.primaryFocus?._setAsFocusedChildForScope();
} }
if (oldScope != null && child.context != null && child.enclosingScope != oldScope) { 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) { if (child._requestFocusWhenReparented) {
child._doRequestFocus(findFirstFocus: true); child._doRequestFocus(findFirstFocus: true);
...@@ -1145,19 +1145,19 @@ class FocusNode with DiagnosticableTreeMixin, ChangeNotifier { ...@@ -1145,19 +1145,19 @@ class FocusNode with DiagnosticableTreeMixin, ChangeNotifier {
/// [FocusTraversalPolicy.next] method. /// [FocusTraversalPolicy.next] method.
/// ///
/// Returns true if it successfully found a node and requested focus. /// 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 /// Request to move the focus to the previous focus node, by calling the
/// [FocusTraversalPolicy.previous] method. /// [FocusTraversalPolicy.previous] method.
/// ///
/// Returns true if it successfully found a node and requested focus. /// 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 /// Request to move the focus to the nearest focus node in the given
/// direction, by calling the [FocusTraversalPolicy.inDirection] method. /// direction, by calling the [FocusTraversalPolicy.inDirection] method.
/// ///
/// Returns true if it successfully found a node and requested focus. /// 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 @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
......
...@@ -433,21 +433,24 @@ class Focus extends StatefulWidget { ...@@ -433,21 +433,24 @@ class Focus extends StatefulWidget {
/// ///
/// If no [Focus] node is found before reaching the nearest [FocusScope] /// If no [Focus] node is found before reaching the nearest [FocusScope]
/// widget, or there is no [Focus] widget in scope, then this method will /// 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 /// throw an exception.
/// [nullOk].
/// ///
/// 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 /// Calling this function creates a dependency that will rebuild the given
/// context when the focus changes. /// 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(context != null);
assert(nullOk != null);
assert(scopeOk != null); assert(scopeOk != null);
final _FocusMarker? marker = context.dependOnInheritedWidgetOfExactType<_FocusMarker>(); final _FocusMarker? marker = context.dependOnInheritedWidgetOfExactType<_FocusMarker>();
final FocusNode? node = marker?.notifier; final FocusNode? node = marker?.notifier;
if (node == null) { assert(() {
if (!nullOk) { if (node == null) {
throw FlutterError( throw FlutterError(
'Focus.of() was called with a context that does not contain a Focus widget.\n' '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 ' 'No Focus widget ancestor could be found starting from the context that was passed to '
...@@ -457,10 +460,10 @@ class Focus extends StatefulWidget { ...@@ -457,10 +460,10 @@ class Focus extends StatefulWidget {
' $context' ' $context'
); );
} }
return null; return true;
} }());
if (!scopeOk && node is FocusScopeNode) { assert(() {
if (!nullOk) { if (!scopeOk && node is FocusScopeNode) {
throw FlutterError( throw FlutterError(
'Focus.of() was called with a context that does not contain a Focus between the given ' 'Focus.of() was called with a context that does not contain a Focus between the given '
'context and the nearest FocusScope widget.\n' 'context and the nearest FocusScope widget.\n'
...@@ -472,6 +475,36 @@ class Focus extends StatefulWidget { ...@@ -472,6 +475,36 @@ class Focus extends StatefulWidget {
' $context' ' $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 null;
} }
return node; return node;
...@@ -489,7 +522,7 @@ class Focus extends StatefulWidget { ...@@ -489,7 +522,7 @@ class Focus extends StatefulWidget {
/// ///
/// Calling this function creates a dependency that will rebuild the given /// Calling this function creates a dependency that will rebuild the given
/// context when the focus changes. /// 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 @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
......
...@@ -1363,7 +1363,7 @@ class OrderedTraversalPolicy extends FocusTraversalPolicy with DirectionalFocusT ...@@ -1363,7 +1363,7 @@ class OrderedTraversalPolicy extends FocusTraversalPolicy with DirectionalFocusT
final List<FocusNode> unordered = <FocusNode>[]; final List<FocusNode> unordered = <FocusNode>[];
final List<_OrderedFocusInfo> ordered = <_OrderedFocusInfo>[]; final List<_OrderedFocusInfo> ordered = <_OrderedFocusInfo>[];
for (final FocusNode node in sortedDescendants) { 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) { if (order != null) {
ordered.add(_OrderedFocusInfo(node: node, order: order)); ordered.add(_OrderedFocusInfo(node: node, order: order));
} else { } else {
...@@ -1393,30 +1393,49 @@ class OrderedTraversalPolicy extends FocusTraversalPolicy with DirectionalFocusT ...@@ -1393,30 +1393,49 @@ class OrderedTraversalPolicy extends FocusTraversalPolicy with DirectionalFocusT
/// [FocusTraversalOrder.of] for a particular context. /// [FocusTraversalOrder.of] for a particular context.
class FocusTraversalOrder extends InheritedWidget { class FocusTraversalOrder extends InheritedWidget {
/// A const constructor so that subclasses can be const. /// 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]. /// The order for the widget descendants of this [FocusTraversalOrder].
final FocusOrder? order; final FocusOrder order;
/// Finds the [FocusOrder] in the nearest ancestor [FocusTraversalOrder] widget. /// Finds the [FocusOrder] in the nearest ancestor [FocusTraversalOrder] widget.
/// ///
/// It does not create a rebuild dependency because changing the traversal /// 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 /// order doesn't change the widget tree, so nothing needs to be rebuilt as a
/// result of an order change. /// 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(context != null);
assert(nullOk != null);
final FocusTraversalOrder? marker = context.getElementForInheritedWidgetOfExactType<FocusTraversalOrder>()?.widget as FocusTraversalOrder?; final FocusTraversalOrder? marker = context.getElementForInheritedWidgetOfExactType<FocusTraversalOrder>()?.widget as FocusTraversalOrder?;
final FocusOrder? order = marker?.order; assert((){
if (order == null && !nullOk) { if (marker == null) {
throw FlutterError('FocusTraversalOrder.of() was called with a context that ' throw FlutterError(
'does not contain a TraversalOrder widget. No TraversalOrder widget ' '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 ' 'ancestor could be found starting from the context that was passed to '
'FocusTraversalOrder.of().\n' 'FocusTraversalOrder.of().\n'
'The context used was:\n' 'The context used was:\n'
' $context'); ' $context',
} );
return order; }
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<FocusTraversalOrder>()?.widget as FocusTraversalOrder?;
return marker?.order;
} }
// Since the order of traversal doesn't affect display of anything, we don't // Since the order of traversal doesn't affect display of anything, we don't
...@@ -1670,17 +1689,16 @@ class FocusTraversalGroup extends StatefulWidget { ...@@ -1670,17 +1689,16 @@ class FocusTraversalGroup extends StatefulWidget {
/// order doesn't change the widget tree, so nothing needs to be rebuilt as a /// order doesn't change the widget tree, so nothing needs to be rebuilt as a
/// result of an order change. /// 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 /// See also:
/// [FocusTraversalGroup] ancestor. ///
static FocusTraversalPolicy? of(BuildContext context, {bool nullOk = false}) { /// * [maybeOf] for a similar function that will return null if no
/// [FocusTraversalGroup] ancestor is found.
static FocusTraversalPolicy of(BuildContext context) {
assert(context != null); assert(context != null);
final _FocusTraversalGroupMarker? inherited = context.dependOnInheritedWidgetOfExactType<_FocusTraversalGroupMarker>(); final _FocusTraversalGroupMarker? inherited = context.dependOnInheritedWidgetOfExactType<_FocusTraversalGroupMarker>();
assert(() { assert(() {
if (nullOk) {
return true;
}
if (inherited == null) { if (inherited == null) {
throw FlutterError( throw FlutterError(
'Unable to find a FocusTraversalGroup widget in the context.\n' 'Unable to find a FocusTraversalGroup widget in the context.\n'
...@@ -1696,6 +1714,25 @@ class FocusTraversalGroup extends StatefulWidget { ...@@ -1696,6 +1714,25 @@ class FocusTraversalGroup extends StatefulWidget {
} }
return true; 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; return inherited?.policy;
} }
......
...@@ -98,7 +98,7 @@ void main() { ...@@ -98,7 +98,7 @@ void main() {
); );
await tester.pump(); await tester.pump();
expect(Focus.of(childKey.currentContext!, nullOk: true)!.hasPrimaryFocus, isTrue); expect(Focus.maybeOf(childKey.currentContext!)!.hasPrimaryFocus, isTrue);
await tester.pumpWidget( await tester.pumpWidget(
wrap( wrap(
...@@ -112,7 +112,7 @@ void main() { ...@@ -112,7 +112,7 @@ void main() {
); );
await tester.pump(); 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 { testWidgets('CheckboxListTile contentPadding test', (WidgetTester tester) async {
......
...@@ -2328,7 +2328,7 @@ void main() { ...@@ -2328,7 +2328,7 @@ void main() {
await tester.pump(); await tester.pump();
await tester.pump(const Duration(seconds: 1)); // finish the menu open animation await tester.pump(const Duration(seconds: 1)); // finish the menu open animation
expect(value, equals('one')); expect(value, equals('one'));
expect(Focus.of(tester.element(find.byKey(const ValueKey<String>('one')).last))!.hasPrimaryFocus, isTrue); expect(Focus.of(tester.element(find.byKey(const ValueKey<String>('one')).last)).hasPrimaryFocus, isTrue);
await tester.sendKeyEvent(LogicalKeyboardKey.tab); // Focus 'two' await tester.sendKeyEvent(LogicalKeyboardKey.tab); // Focus 'two'
await tester.pump(); await tester.pump();
...@@ -2345,7 +2345,7 @@ void main() { ...@@ -2345,7 +2345,7 @@ void main() {
await tester.pump(const Duration(seconds: 1)); // finish the menu open animation await tester.pump(const Duration(seconds: 1)); // finish the menu open animation
expect(value, equals('two')); expect(value, equals('two'));
final Element element = tester.element(find.byKey(const ValueKey<String>('two')).last); final Element element = tester.element(find.byKey(const ValueKey<String>('two')).last);
final FocusNode node = Focus.of(element)!; final FocusNode node = Focus.of(element);
expect(node.hasFocus, isTrue); expect(node.hasFocus, isTrue);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/55320 }, skip: isBrowser); // https://github.com/flutter/flutter/issues/55320
...@@ -2392,7 +2392,7 @@ void main() { ...@@ -2392,7 +2392,7 @@ void main() {
await tester.pump(); await tester.pump();
await tester.pump(const Duration(seconds: 1)); // finish the menu open animation await tester.pump(const Duration(seconds: 1)); // finish the menu open animation
expect(value, equals(1)); expect(value, equals(1));
expect(Focus.of(tester.element(find.byKey(const ValueKey<int>(1)).last))!.hasPrimaryFocus, isTrue); expect(Focus.of(tester.element(find.byKey(const ValueKey<int>(1)).last)).hasPrimaryFocus, isTrue);
for (int i = 0; i < 41; ++i) { for (int i = 0; i < 41; ++i) {
await tester.sendKeyEvent(LogicalKeyboardKey.tab); // Move to the next one. await tester.sendKeyEvent(LogicalKeyboardKey.tab); // Move to the next one.
...@@ -2408,7 +2408,7 @@ void main() { ...@@ -2408,7 +2408,7 @@ void main() {
await tester.pump(const Duration(seconds: 1)); // finish the menu open animation await tester.pump(const Duration(seconds: 1)); // finish the menu open animation
expect(value, equals(42)); expect(value, equals(42));
final Element element = tester.element(find.byKey(const ValueKey<int>(42)).last); final Element element = tester.element(find.byKey(const ValueKey<int>(42)).last);
final FocusNode node = Focus.of(element)!; final FocusNode node = Focus.of(element);
expect(node.hasFocus, isTrue); expect(node.hasFocus, isTrue);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/55320 }, skip: isBrowser); // https://github.com/flutter/flutter/issues/55320
...@@ -2454,14 +2454,14 @@ void main() { ...@@ -2454,14 +2454,14 @@ void main() {
await tester.sendKeyEvent(LogicalKeyboardKey.enter); await tester.sendKeyEvent(LogicalKeyboardKey.enter);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(value, equals(1)); expect(value, equals(1));
expect(Focus.of(tester.element(find.byKey(const ValueKey<int>(1)).last))!.hasPrimaryFocus, isTrue); expect(Focus.of(tester.element(find.byKey(const ValueKey<int>(1)).last)).hasPrimaryFocus, isTrue);
// Move to an item very far down the menu. // Move to an item very far down the menu.
for (int i = 0; i < 90; ++i) { for (int i = 0; i < 90; ++i) {
await tester.sendKeyEvent(LogicalKeyboardKey.tab); // Move to the next one. await tester.sendKeyEvent(LogicalKeyboardKey.tab); // Move to the next one.
await tester.pumpAndSettle(); // Wait for it to animate the menu. await tester.pumpAndSettle(); // Wait for it to animate the menu.
} }
expect(Focus.of(tester.element(find.byKey(const ValueKey<int>(91)).last))!.hasPrimaryFocus, isTrue); expect(Focus.of(tester.element(find.byKey(const ValueKey<int>(91)).last)).hasPrimaryFocus, isTrue);
// Scroll back to the top using touch, and make sure we end up there. // Scroll back to the top using touch, and make sure we end up there.
final Finder menu = find.byWidgetPredicate((Widget widget) { final Finder menu = find.byWidgetPredicate((Widget widget) {
...@@ -2483,7 +2483,7 @@ void main() { ...@@ -2483,7 +2483,7 @@ void main() {
// Scrolling to the top again has removed the one the focus was on from the // Scrolling to the top again has removed the one the focus was on from the
// tree, causing it to lose focus. // tree, causing it to lose focus.
expect(Focus.of(tester.element(find.byKey(const ValueKey<int>(91)).last))!.hasPrimaryFocus, isFalse); expect(Focus.of(tester.element(find.byKey(const ValueKey<int>(91)).last)).hasPrimaryFocus, isFalse);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/55320 }, skip: isBrowser); // https://github.com/flutter/flutter/issues/55320
testWidgets('DropdownButton onTap callback is called when defined', (WidgetTester tester) async { testWidgets('DropdownButton onTap callback is called when defined', (WidgetTester tester) async {
......
...@@ -1173,10 +1173,10 @@ void main() { ...@@ -1173,10 +1173,10 @@ void main() {
); );
await tester.pump(); // Let the focus take effect. await tester.pump(); // Let the focus take effect.
final FocusNode? tileNode = Focus.of(childKey.currentContext!); final FocusNode tileNode = Focus.of(childKey.currentContext!);
tileNode!.requestFocus(); tileNode.requestFocus();
await tester.pump(); // Let the focus take effect. 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); expect(tileNode.hasPrimaryFocus, isTrue);
await tester.pumpWidget( await tester.pumpWidget(
...@@ -1197,7 +1197,7 @@ void main() { ...@@ -1197,7 +1197,7 @@ void main() {
); );
expect(tester.binding.focusManager.primaryFocus, isNot(equals(tileNode))); 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 { testWidgets('ListTile can autofocus unless disabled.', (WidgetTester tester) async {
...@@ -1222,7 +1222,7 @@ void main() { ...@@ -1222,7 +1222,7 @@ void main() {
); );
await tester.pump(); await tester.pump();
expect(Focus.of(childKey.currentContext!, nullOk: true)!.hasPrimaryFocus, isTrue); expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isTrue);
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -1243,7 +1243,7 @@ void main() { ...@@ -1243,7 +1243,7 @@ void main() {
); );
await tester.pump(); 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 { testWidgets('ListTile is focusable and has correct focus color', (WidgetTester tester) async {
......
...@@ -189,7 +189,7 @@ void main() { ...@@ -189,7 +189,7 @@ void main() {
await tester.pumpWidget(buildApp(directional: true)); await tester.pumpWidget(buildApp(directional: true));
// Try to bring up the popup menu and select the first item from it // 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.pumpAndSettle();
await tester.tap(find.byKey(popupButtonKey)); await tester.tap(find.byKey(popupButtonKey));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
...@@ -238,10 +238,10 @@ void main() { ...@@ -238,10 +238,10 @@ void main() {
), ),
), ),
); );
Focus.of(childKey.currentContext!)!.requestFocus(); Focus.of(childKey.currentContext!).requestFocus();
await tester.pump(); await tester.pump();
expect(Focus.of(childKey.currentContext!)!.hasPrimaryFocus, isFalse); expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isFalse);
expect(itemBuilderCalled, isFalse); expect(itemBuilderCalled, isFalse);
expect(onSelectedCalled, isFalse); expect(onSelectedCalled, isFalse);
}); });
...@@ -281,10 +281,10 @@ void main() { ...@@ -281,10 +281,10 @@ void main() {
}), }),
), ),
); );
Focus.of(childKey.currentContext!)!.requestFocus(); Focus.of(childKey.currentContext!).requestFocus();
await tester.pump(); 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 { testWidgets('PopupMenuItem is only focusable when enabled', (WidgetTester tester) async {
...@@ -319,7 +319,7 @@ void main() { ...@@ -319,7 +319,7 @@ void main() {
// Open the popup to build and show the menu contents. // Open the popup to build and show the menu contents.
await tester.tap(find.byKey(popupButtonKey)); await tester.tap(find.byKey(popupButtonKey));
await tester.pumpAndSettle(); 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. // Now that the contents are shown, request focus on the child text.
childNode.requestFocus(); childNode.requestFocus();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
...@@ -362,7 +362,7 @@ void main() { ...@@ -362,7 +362,7 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(itemBuilderCalled, isTrue); 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 { testWidgets('PopupMenuButton is horizontal on iOS', (WidgetTester tester) async {
......
...@@ -589,7 +589,7 @@ void main() { ...@@ -589,7 +589,7 @@ void main() {
); );
await tester.pump(); await tester.pump();
expect(Focus.of(childKey.currentContext!)!.hasPrimaryFocus, isTrue); expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isTrue);
await tester.pumpWidget( await tester.pumpWidget(
wrap( wrap(
...@@ -604,7 +604,7 @@ void main() { ...@@ -604,7 +604,7 @@ void main() {
); );
await tester.pump(); await tester.pump();
expect(Focus.of(childKey.currentContext!)!.hasPrimaryFocus, isFalse); expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isFalse);
}); });
testWidgets('RadioListTile contentPadding test', (WidgetTester tester) async { testWidgets('RadioListTile contentPadding test', (WidgetTester tester) async {
......
...@@ -624,7 +624,7 @@ void main() { ...@@ -624,7 +624,7 @@ void main() {
); );
await tester.pump(); 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(); disabledNode.requestFocus();
await tester.pump(); await tester.pump();
expect(disabledNode.hasPrimaryFocus, isFalse); expect(disabledNode.hasPrimaryFocus, isFalse);
...@@ -650,7 +650,7 @@ void main() { ...@@ -650,7 +650,7 @@ void main() {
); );
await tester.pump(); 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(); disabledNode.requestFocus();
await tester.pump(); await tester.pump();
expect(disabledNode.hasPrimaryFocus, isFalse); expect(disabledNode.hasPrimaryFocus, isFalse);
......
...@@ -276,7 +276,7 @@ void main() { ...@@ -276,7 +276,7 @@ void main() {
); );
await tester.pump(); await tester.pump();
expect(Focus.of(childKey.currentContext!)!.hasPrimaryFocus, isTrue); expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isTrue);
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -296,7 +296,7 @@ void main() { ...@@ -296,7 +296,7 @@ void main() {
); );
await tester.pump(); await tester.pump();
expect(Focus.of(childKey.currentContext!)!.hasPrimaryFocus, isFalse); expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isFalse);
}); });
testWidgets('SwitchListTile controlAffinity test', (WidgetTester tester) async { testWidgets('SwitchListTile controlAffinity test', (WidgetTester tester) async {
......
...@@ -1597,8 +1597,8 @@ void main() { ...@@ -1597,8 +1597,8 @@ void main() {
await tester.testTextInput.receiveAction(action); await tester.testTextInput.receiveAction(action);
await tester.pump(); await tester.pump();
expect(Focus.of(nextKey.currentContext!)!.hasFocus, equals(shouldFocusNext)); expect(Focus.of(nextKey.currentContext!).hasFocus, equals(shouldFocusNext));
expect(Focus.of(previousKey.currentContext!)!.hasFocus, equals(shouldFocusPrevious)); expect(Focus.of(previousKey.currentContext!).hasFocus, equals(shouldFocusPrevious));
expect(focusNode.hasFocus, equals(!shouldLoseFocus)); expect(focusNode.hasFocus, equals(!shouldLoseFocus));
} }
......
...@@ -991,7 +991,7 @@ void main() { ...@@ -991,7 +991,7 @@ void main() {
); );
final Element containerElement = tester.element(find.byKey(containerKey)); final Element containerElement = tester.element(find.byKey(containerKey));
final FocusNode androidViewFocusNode = androidViewFocusWidget.focusNode!; final FocusNode androidViewFocusNode = androidViewFocusWidget.focusNode!;
final FocusNode containerFocusNode = Focus.of(containerElement)!; final FocusNode containerFocusNode = Focus.of(containerElement);
containerFocusNode.requestFocus(); containerFocusNode.requestFocus();
...@@ -1038,7 +1038,7 @@ void main() { ...@@ -1038,7 +1038,7 @@ void main() {
final Element containerElement = tester.element(find.byKey(containerKey)); final Element containerElement = tester.element(find.byKey(containerKey));
final FocusNode containerFocusNode = Focus.of(containerElement)!; final FocusNode containerFocusNode = Focus.of(containerElement);
containerFocusNode.requestFocus(); containerFocusNode.requestFocus();
await tester.pump(); await tester.pump();
...@@ -1086,7 +1086,7 @@ void main() { ...@@ -1086,7 +1086,7 @@ void main() {
viewsController.createCompleter!.complete(); viewsController.createCompleter!.complete();
final Element containerElement = tester.element(find.byKey(containerKey)); final Element containerElement = tester.element(find.byKey(containerKey));
final FocusNode containerFocusNode = Focus.of(containerElement)!; final FocusNode containerFocusNode = Focus.of(containerElement);
containerFocusNode.requestFocus(); containerFocusNode.requestFocus();
await tester.pump(); await tester.pump();
...@@ -2491,7 +2491,7 @@ void main() { ...@@ -2491,7 +2491,7 @@ void main() {
); );
final FocusNode platformViewFocusNode = platformViewFocusWidget.focusNode!; final FocusNode platformViewFocusNode = platformViewFocusWidget.focusNode!;
final Element containerElement = tester.element(find.byKey(containerKey)); final Element containerElement = tester.element(find.byKey(containerKey));
final FocusNode containerFocusNode = Focus.of(containerElement)!; final FocusNode containerFocusNode = Focus.of(containerElement);
containerFocusNode.requestFocus(); containerFocusNode.requestFocus();
await tester.pump(); await tester.pump();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment