Unverified Commit 266fb87c authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Update the Focus widget to update the node's onKey handler when the widget updates (#74909)

This updates the onKey handler of the FocusNode that the Focus widget manages when the widget is updated and the handler has changed. Also added a setter for onKey to the FocusNode.
parent 9d5a540c
......@@ -432,7 +432,7 @@ class FocusNode with DiagnosticableTreeMixin, ChangeNotifier {
/// arguments must not be null.
FocusNode({
String? debugLabel,
FocusOnKeyCallback? onKey,
this.onKey,
bool skipTraversal = false,
bool canRequestFocus = true,
bool descendantsAreFocusable = true,
......@@ -441,8 +441,7 @@ class FocusNode with DiagnosticableTreeMixin, ChangeNotifier {
assert(descendantsAreFocusable != null),
_skipTraversal = skipTraversal,
_canRequestFocus = canRequestFocus,
_descendantsAreFocusable = descendantsAreFocusable,
_onKey = onKey {
_descendantsAreFocusable = descendantsAreFocusable {
// Set it via the setter so that it does nothing on release builds.
this.debugLabel = debugLabel;
}
......@@ -573,8 +572,7 @@ class FocusNode with DiagnosticableTreeMixin, ChangeNotifier {
/// [hasFocus] returns true).
///
/// {@macro flutter.widgets.FocusNode.keyEvents}
FocusOnKeyCallback? get onKey => _onKey;
FocusOnKeyCallback? _onKey;
FocusOnKeyCallback? onKey;
FocusManager? _manager;
List<FocusNode>? _ancestors;
......@@ -1028,7 +1026,7 @@ class FocusNode with DiagnosticableTreeMixin, ChangeNotifier {
@mustCallSuper
FocusAttachment attach(BuildContext? context, {FocusOnKeyCallback? onKey}) {
_context = context;
_onKey = onKey ?? _onKey;
this.onKey = onKey ?? this.onKey;
_attachment = FocusAttachment._(this);
return _attachment!;
}
......
......@@ -643,6 +643,9 @@ class _FocusState extends State<Focus> {
}());
if (oldWidget.focusNode == widget.focusNode) {
if (widget.onKey != focusNode.onKey) {
focusNode.onKey = widget.onKey;
}
if (widget.skipTraversal != null) {
focusNode.skipTraversal = widget.skipTraversal!;
}
......
......@@ -4,9 +4,10 @@
import 'dart:ui';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/semantics.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'semantics_tester.dart';
......@@ -1593,6 +1594,37 @@ void main() {
final TestSemantics expectedSemantics = TestSemantics.root();
expect(semantics, hasSemantics(expectedSemantics));
});
testWidgets('Focus updates the onKey handler when the widget updates', (WidgetTester tester) async {
final GlobalKey key1 = GlobalKey(debugLabel: '1');
final FocusNode focusNode = FocusNode();
bool? keyEventHandled;
await tester.pumpWidget(
Focus(
onKey: (_, __) => true, // This one does nothing.
focusNode: focusNode,
child: Container(key: key1),
),
);
Focus.of(key1.currentContext!).requestFocus();
await tester.pump();
await tester.sendKeyEvent(LogicalKeyboardKey.enter);
expect(keyEventHandled, isNull);
await tester.pumpWidget(
Focus(
onKey: (FocusNode node, RawKeyEvent event) { // The updated handler handles the key.
keyEventHandled = true;
return true;
},
focusNode: focusNode,
child: Container(key: key1),
),
);
await tester.sendKeyEvent(LogicalKeyboardKey.enter);
expect(keyEventHandled, isTrue);
});
});
group('ExcludeFocus', () {
testWidgets("Descendants of ExcludeFocus aren't focusable.", (WidgetTester tester) async {
......
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