mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Add parentNode to FocusScope widget (#114034)
This commit is contained in:
parent
3ce88d3813
commit
8c3806f817
@ -760,6 +760,7 @@ class FocusScope extends Focus {
|
||||
const FocusScope({
|
||||
super.key,
|
||||
FocusScopeNode? node,
|
||||
super.parentNode,
|
||||
required super.child,
|
||||
super.autofocus,
|
||||
super.onFocusChange,
|
||||
@ -781,6 +782,7 @@ class FocusScope extends Focus {
|
||||
Key? key,
|
||||
required Widget child,
|
||||
required FocusScopeNode focusScopeNode,
|
||||
FocusNode? parentNode,
|
||||
bool autofocus,
|
||||
ValueChanged<bool>? onFocusChange,
|
||||
}) = _FocusScopeWithExternalFocusNode;
|
||||
@ -809,13 +811,13 @@ class _FocusScopeWithExternalFocusNode extends FocusScope {
|
||||
super.key,
|
||||
required super.child,
|
||||
required FocusScopeNode focusScopeNode,
|
||||
super.parentNode,
|
||||
super.autofocus,
|
||||
super.onFocusChange,
|
||||
}) : super(
|
||||
node: focusScopeNode,
|
||||
);
|
||||
|
||||
|
||||
@override
|
||||
bool get _usingExternalFocus => true;
|
||||
@override
|
||||
@ -846,7 +848,7 @@ class _FocusScopeState extends _FocusState {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_focusAttachment!.reparent();
|
||||
_focusAttachment!.reparent(parent: widget.parentNode);
|
||||
return Semantics(
|
||||
explicitChildNodes: true,
|
||||
child: _FocusMarker(
|
||||
|
@ -532,6 +532,72 @@ void main() {
|
||||
expect(insertedNode.hasFocus, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('Setting parentNode determines focus scope tree hierarchy.', (WidgetTester tester) async {
|
||||
final FocusScopeNode topNode = FocusScopeNode(debugLabel: 'Top');
|
||||
final FocusScopeNode parentNode = FocusScopeNode(debugLabel: 'Parent');
|
||||
final FocusScopeNode childNode = FocusScopeNode(debugLabel: 'Child');
|
||||
final FocusScopeNode insertedNode = FocusScopeNode(debugLabel: 'Inserted');
|
||||
|
||||
await tester.pumpWidget(
|
||||
FocusScope.withExternalFocusNode(
|
||||
focusScopeNode: topNode,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
FocusScope.withExternalFocusNode(
|
||||
focusScopeNode: parentNode,
|
||||
child: const SizedBox(),
|
||||
),
|
||||
FocusScope.withExternalFocusNode(
|
||||
focusScopeNode: childNode,
|
||||
parentNode: parentNode,
|
||||
child: const Focus(
|
||||
autofocus: true,
|
||||
child: SizedBox(),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pump();
|
||||
|
||||
expect(childNode.hasFocus, isTrue);
|
||||
expect(parentNode.hasFocus, isTrue);
|
||||
expect(topNode.hasFocus, isTrue);
|
||||
|
||||
// Check that inserting a Focus in between doesn't reparent the child.
|
||||
await tester.pumpWidget(
|
||||
FocusScope.withExternalFocusNode(
|
||||
focusScopeNode: topNode,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
FocusScope.withExternalFocusNode(
|
||||
focusScopeNode: parentNode,
|
||||
child: const SizedBox(),
|
||||
),
|
||||
FocusScope.withExternalFocusNode(
|
||||
focusScopeNode: insertedNode,
|
||||
child: FocusScope.withExternalFocusNode(
|
||||
focusScopeNode: childNode,
|
||||
parentNode: parentNode,
|
||||
child: const Focus(
|
||||
autofocus: true,
|
||||
child: SizedBox(),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pump();
|
||||
|
||||
expect(childNode.hasFocus, isTrue);
|
||||
expect(parentNode.hasFocus, isTrue);
|
||||
expect(topNode.hasFocus, isTrue);
|
||||
expect(insertedNode.hasFocus, isFalse);
|
||||
});
|
||||
|
||||
// Arguably, this isn't correct behavior, but it is what happens now.
|
||||
testWidgets("Removing focused widget doesn't move focus to next widget within FocusScope", (WidgetTester tester) async {
|
||||
final GlobalKey<TestFocusState> keyA = GlobalKey();
|
||||
|
Loading…
Reference in New Issue
Block a user