mirror of
https://github.com/flutter/flutter
synced 2024-10-13 11:42:54 +00:00
Don't crash when TextField w/ explicit controller is activated via a11y (#17892)
Fixes #17801.
This commit is contained in:
parent
c4d6311a29
commit
1361071a21
|
@ -506,8 +506,8 @@ class _TextFieldState extends State<TextField> with AutomaticKeepAliveClientMixi
|
|||
|
||||
return new Semantics(
|
||||
onTap: () {
|
||||
if (!_controller.selection.isValid)
|
||||
_controller.selection = new TextSelection.collapsed(offset: _controller.text.length);
|
||||
if (!_effectiveController.selection.isValid)
|
||||
_effectiveController.selection = new TextSelection.collapsed(offset: _effectiveController.text.length);
|
||||
_requestKeyboard();
|
||||
},
|
||||
child: new IgnorePointer(
|
||||
|
|
|
@ -2059,6 +2059,76 @@ void main() {
|
|||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('Can activate TextField with explicit controller via semantics ', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/17801
|
||||
|
||||
const String textInTextField = 'Hello';
|
||||
|
||||
final SemanticsTester semantics = new SemanticsTester(tester);
|
||||
final SemanticsOwner semanticsOwner = tester.binding.pipelineOwner.semanticsOwner;
|
||||
final TextEditingController controller = new TextEditingController()
|
||||
..text = textInTextField;
|
||||
final Key key = new UniqueKey();
|
||||
|
||||
await tester.pumpWidget(
|
||||
overlay(
|
||||
child: new TextField(
|
||||
key: key,
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
const int inputFieldId = 1;
|
||||
|
||||
expect(semantics, hasSemantics(
|
||||
new TestSemantics.root(
|
||||
children: <TestSemantics>[
|
||||
new TestSemantics(
|
||||
id: inputFieldId,
|
||||
flags: <SemanticsFlag>[SemanticsFlag.isTextField],
|
||||
actions: <SemanticsAction>[SemanticsAction.tap],
|
||||
value: textInTextField,
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
],
|
||||
),
|
||||
ignoreRect: true, ignoreTransform: true,
|
||||
));
|
||||
|
||||
semanticsOwner.performAction(inputFieldId, SemanticsAction.tap);
|
||||
await tester.pump();
|
||||
|
||||
expect(semantics, hasSemantics(
|
||||
new TestSemantics.root(
|
||||
children: <TestSemantics>[
|
||||
new TestSemantics(
|
||||
id: inputFieldId,
|
||||
flags: <SemanticsFlag>[
|
||||
SemanticsFlag.isTextField,
|
||||
SemanticsFlag.isFocused,
|
||||
],
|
||||
actions: <SemanticsAction>[
|
||||
SemanticsAction.tap,
|
||||
SemanticsAction.moveCursorBackwardByCharacter,
|
||||
SemanticsAction.setSelection,
|
||||
SemanticsAction.paste,
|
||||
],
|
||||
value: textInTextField,
|
||||
textDirection: TextDirection.ltr,
|
||||
textSelection: const TextSelection(
|
||||
baseOffset: textInTextField.length,
|
||||
extentOffset: textInTextField.length,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
ignoreRect: true, ignoreTransform: true,
|
||||
));
|
||||
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('TextField throws when not descended from a Material widget', (WidgetTester tester) async {
|
||||
const Widget textField = const TextField();
|
||||
await tester.pumpWidget(textField);
|
||||
|
|
Loading…
Reference in a new issue