Add a field, `currentTextEditingValue`, to the `TextInputClient` interface to get the current value of an editable text field from a platform client.
Original behavior
The `TextInputClient` class is used by the Flutter framework to communicate with platform code about the current state of text input widgets like `EditableText`.
New behavior
On some supported platforms, the application can be moved into the background where it is expected to consume fewer resources. For example, a backgrounded application on Android should avoid consuming unnecessary memory and has no need to retain references to views. Before this change, the Android-specific platform code could lose state information about editable text fields when the app moved back to the foreground. This is seen, for example, when text entered in a `TextField` widget is lost to the Java code, but is still remembered in the Dart code.
- Who is affected
- Applications and packages relying on the previous behaviour or signature. Code that uses TextInputClient, EditableText, TextEditingValue and related APIs.
- Practical impact
- Behaviour or API differences that can break builds or change runtime behaviour.
- What action should I take?
- Follow the official migration guide below, update affected call sites, run `dart fix --apply` where a fix is available, then run your tests.
Before and after (from the official guide)
| 1 | class _MyCustomTextWidgetState extends State<MyCustomWidget> implements TextEditingClient { | |
| 2 | ... | |
| 3 | ||
| 4 | @override | |
| 5 | void updateEditingValue(TextEditingValue value) { | |
| 6 | ... | |
| 7 | } | |
| 8 | ||
| 9 | @override | |
| 10 | void performAction(TextInputAction action) { | |
| 11 | ... | |
| 12 | } | |
| 13 | ||
| 14 | @override | |
| 15 | void updateFloatingCursor(RawFloatingCursorPoint point) { | |
| 16 | ... | |
| 17 | } | |
| 18 | } |
| 1 | class _MyCustomTextWidgetState extends State<MyCustomWidget> implements TextEditingClient { | |
| 2 | ... | |
| 3 | ||
| 4 | @override | |
| 5 | + | TextEditingValue get currentTextEditingValue => widget.textEditingController.value; |
| 6 | + | |
| 7 | + | @override |
| 8 | void updateEditingValue(TextEditingValue value) { | |
| 9 | ... | |
| 10 | } | |
| 11 | ||
| 12 | @override | |
| 13 | void performAction(TextInputAction action) { | |
| 14 | ... | |
| 15 | } | |
| 16 | ||
| 17 | @override | |
| 18 | void updateFloatingCursor(RawFloatingCursorPoint point) { | |
| 19 | ... | |
| 20 | } | |
| 21 | } |
Raw before / after
class _MyCustomTextWidgetState extends State<MyCustomWidget> implements TextEditingClient {
...
@override
void updateEditingValue(TextEditingValue value) {
...
}
@override
void performAction(TextInputAction action) {
...
}
@override
void updateFloatingCursor(RawFloatingCursorPoint point) {
...
}
}class _MyCustomTextWidgetState extends State<MyCustomWidget> implements TextEditingClient {
...
@override
TextEditingValue get currentTextEditingValue => widget.textEditingController.value;
@override
void updateEditingValue(TextEditingValue value) {
...
}
@override
void performAction(TextInputAction action) {
...
}
@override
void updateFloatingCursor(RawFloatingCursorPoint point) {
...
}
}Official migration guide (excerpt, © The Flutter Authors, CC BY 3.0)
If you previously implemented or extended TextEditingClient,
you must now add the appropriate override for currentTextEditingValue.
This value may be null.
If you want to migrate before this change lands, you can add a class to your class similar to the following:
abstract class _TemporaryTextEditingClient {
TextEditingValue get currentTextEditingValue;
}This allows you to add the new member with an
@override annotation before the change lands
in the framework. Later, you can remove the
temporary interface definition.
Code before migration:
class _MyCustomTextWidgetState extends State<MyCustomWidget> implements TextEditingClient {
...
@override
void updateEditingValue(TextEditingValue value) {
...
}
@override
void performAction(TextInputAction action) {
...
}
@override
void updateFloatingCursor(RawFloatingCursorPoint point) {
...
}
}Code after migration:
class _MyCustomTextWidgetState extends State<MyCustomWidget> implements TextEditingClient {
...
@override
TextEditingValue get currentTextEditingValue => widget.textEditingController.value;
@override
void updateEditingValue(TextEditingValue value) {
...
}
@override
void performAction(TextInputAction action) {
...
}
@override
void updateFloatingCursor(RawFloatingCursorPoint point) {
...
}
}AI_PROVIDER (for example to openai-compatible with a local Ollama or LM Studio endpoint) to enable grounded explanations. Everything else on this page works without an AI provider.Listed in the official breaking-changes index (docs.flutter.dev/release/breaking-changes).
An official announcement or migration guide documents an intended behaviour or API change. A verified source change (git diff) shows code changed but does not by itself prove a public API is breaking. AI interpretations are labelled and never used to classify a change.
- Official migration guide
- TextInput
- TextInputClient
- EditableText
- SystemChannels.textInput
- Issue 47137
- Fix requestExistingInputState response
- Source commit
- b3045439b7c0
- Source last updated
- Oct 21, 2026
- Last synchronized
- Oct 21, 2026
- Publication status
- published
Publication history
- Oct 21, 2026, 8:31 PM: new → published (ingestion) — Backed by an official breaking-change/migration guide.
AI_PROVIDER (for example to openai-compatible with a local Ollama or LM Studio endpoint) to enable grounded explanations. Everything else on this page works without an AI provider.