Unverified Commit c1558f69 authored by fzyzcjy's avatar fzyzcjy Committed by GitHub

Fix `TextField` error in production environment because it wrongly uses...

Fix `TextField` error in production environment because it wrongly uses ancestor render boxes (#126324)

Fixes a crash in a reparented TextField due to frame render phase timing
parent 28605398
......@@ -2672,7 +2672,11 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
if (!_shouldCreateInputConnection) {
_closeInputConnectionIfNeeded();
} else if (oldWidget.readOnly && _hasFocus) {
_openInputConnection();
// _openInputConnection must be called after layout information is available.
// See https://github.com/flutter/flutter/issues/126312
SchedulerBinding.instance.addPostFrameCallback((Duration _) {
_openInputConnection();
});
}
if (kIsWeb && _hasInputConnection) {
......@@ -3133,6 +3137,8 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
/// default.
bool get _needsAutofill => _effectiveAutofillClient.textInputConfiguration.autofillConfiguration.enabled;
// Must be called after layout.
// See https://github.com/flutter/flutter/issues/126312
void _openInputConnection() {
if (!_shouldCreateInputConnection) {
return;
......@@ -3786,6 +3792,8 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
_updateSizeAndTransform();
}
// Must be called after layout.
// See https://github.com/flutter/flutter/issues/126312
void _updateSizeAndTransform() {
final Size size = renderEditable.size;
final Matrix4 transform = renderEditable.getTransformTo(null);
......
......@@ -118,6 +118,48 @@ void main() {
expect(tester.testTextInput.setClientArgs!['inputAction'], equals(serializedActionName));
}
// Regression test for https://github.com/flutter/flutter/issues/126312.
testWidgets('when open input connection in didUpdateWidget, should not throw', (WidgetTester tester) async {
final Key key = GlobalKey();
await tester.pumpWidget(
MaterialApp(
home: EditableText(
key: key,
backgroundCursorColor: Colors.grey,
controller: TextEditingController(text: 'blah blah'),
focusNode: focusNode,
readOnly: true,
style: textStyle,
cursorColor: cursorColor,
selectionControls: materialTextSelectionControls,
),
),
);
focusNode.requestFocus();
await tester.pump();
// Reparent the EditableText, so that the parent has not yet been laid
// out when didUpdateWidget is called.
await tester.pumpWidget(
MaterialApp(
home: FractionalTranslation(
translation: const Offset(0.1, 0.1),
child: EditableText(
key: key,
backgroundCursorColor: Colors.grey,
controller: TextEditingController(text: 'blah blah'),
focusNode: focusNode,
style: textStyle,
cursorColor: cursorColor,
selectionControls: materialTextSelectionControls,
),
),
),
);
});
testWidgets('Text with selection can be shown on the screen when the keyboard shown', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/119628
addTearDown(tester.view.reset);
......
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