mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
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.
This commit is contained in:
parent
9d5a540cbb
commit
266fb87c36
@ -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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user