diff --git a/packages/flutter/lib/src/widgets/editable_text.dart b/packages/flutter/lib/src/widgets/editable_text.dart index 73f2682dc4..e02cea6a99 100644 --- a/packages/flutter/lib/src/widgets/editable_text.dart +++ b/packages/flutter/lib/src/widgets/editable_text.dart @@ -1656,23 +1656,15 @@ class EditableTextState extends State with AutomaticKeepAliveClien // Check if the new value is the same as the current local value, or is the same // as the post-formatting value of the previous pass. final bool textChanged = _value?.text != value?.text; - final bool isRepeatText = value?.text == _lastFormattedUnmodifiedTextEditingValue?.text; - final bool isRepeatSelection = value?.selection == _lastFormattedUnmodifiedTextEditingValue?.selection; - // Only format when the text has changed and there are available formatters. - if (!isRepeatText && textChanged && widget.inputFormatters != null && widget.inputFormatters.isNotEmpty) { - for (final TextInputFormatter formatter in widget.inputFormatters) { + final bool isRepeat = value?.text == _lastFormattedUnmodifiedTextEditingValue?.text; + if (textChanged && !isRepeat && widget.inputFormatters != null && widget.inputFormatters.isNotEmpty) { + for (final TextInputFormatter formatter in widget.inputFormatters) value = formatter.formatEditUpdate(_value, value); - } - } - // If the text has changed or the selection has changed, we should update the - // locally stored TextEditingValue to the new one. - if (!isRepeatText || !isRepeatSelection) { + _value = value; + _updateRemoteEditingValueIfNeeded(); + } else { _value = value; } - // Always attempt to send the value. If the value has changed, then it will send, - // otherwise, it will short-circuit. - _updateRemoteEditingValueIfNeeded(); - if (textChanged && widget.onChanged != null) widget.onChanged(value.text); _lastFormattedUnmodifiedTextEditingValue = _receivedRemoteTextEditingValue; diff --git a/packages/flutter/test/widgets/editable_text_test.dart b/packages/flutter/test/widgets/editable_text_test.dart index 1b4a022448..43e1271032 100644 --- a/packages/flutter/test/widgets/editable_text_test.dart +++ b/packages/flutter/test/widgets/editable_text_test.dart @@ -4238,61 +4238,6 @@ void main() { expect(formatter.log, referenceLog); }); - - testWidgets('formatter logic handles repeat filtering', (WidgetTester tester) async { - final MockTextFormatter formatter = MockTextFormatter(); - await tester.pumpWidget( - MediaQuery( - data: const MediaQueryData(devicePixelRatio: 1.0), - child: Directionality( - textDirection: TextDirection.ltr, - child: FocusScope( - node: focusScopeNode, - autofocus: true, - child: EditableText( - backgroundCursorColor: Colors.grey, - controller: controller, - focusNode: focusNode, - maxLines: 1, // Sets text keyboard implicitly. - style: textStyle, - cursorColor: cursorColor, - inputFormatters: [formatter], - ), - ), - ), - ), - ); - - await tester.tap(find.byType(EditableText)); - await tester.showKeyboard(find.byType(EditableText)); - controller.text = ''; - await tester.idle(); - - final EditableTextState state = - tester.state(find.byType(EditableText)); - expect(tester.testTextInput.editingState['text'], equals('')); - expect(state.wantKeepAlive, true); - - state.updateEditingValue(const TextEditingValue(text: '01')); - state.updateEditingValue(const TextEditingValue(text: '012')); - state.updateEditingValue(const TextEditingValue(text: '0123')); // Text change causes reformat - state.updateEditingValue(const TextEditingValue(text: '0123')); // Repeat, does not format - state.updateEditingValue(const TextEditingValue(text: '0123')); // Repeat, does not format - state.updateEditingValue(const TextEditingValue(text: '0123', selection: TextSelection.collapsed(offset: 2))); // Selection change does not reformat - state.updateEditingValue(const TextEditingValue(text: '0123', selection: TextSelection.collapsed(offset: 2))); // Repeat, does not format - state.updateEditingValue(const TextEditingValue(text: '0123', selection: TextSelection.collapsed(offset: 2))); // Repeat, does not format - - const List referenceLog = [ - '[1]: , 01', - '[1]: normal aa', - '[2]: aa, 012', - '[2]: normal aaaa', - '[3]: aaaa, 0123', - '[3]: normal aaaaaa', - ]; - - expect(formatter.log, referenceLog); - }); } class MockTextFormatter extends TextInputFormatter {