A JSON MethodChannel for handling text input.
This channel exposes a system text input control for interacting with IMEs
(input method editors, for example on-screen keyboards). There is one
control, and at any time it can have one active transaction. Transactions
are represented by an integer. New Transactions are started by
TextInput.setClient. Messages that are sent are assumed to be for the
current transaction (the last "client" set by
Messages received from the shell side specify the transaction to which
they apply, so that stale messages referencing past transactions can be
In debug builds, messages sent with a client ID of -1 are always accepted. This allows tests to smuggle messages without having to mock the engine's text handling (for example, allowing the engine to still handle the text input messages in an integration test).
The methods described below are wrapped in a more convenient form by the TextInput and TextInputConnection class.
The following outgoing methods are defined for this channel (invoked using OptionalMethodChannel.invokeMethod):
TextInput.setClient: Establishes a new transaction. The arguments is a List whose first value is an integer representing a previously unused transaction identifier, and the second is a String with a JSON-encoded object with five keys, as obtained from TextInputConfiguration.toJson. This method must be invoked before any others (except
TextInput.hide). See TextInput.attach.
TextInput.show: Show the keyboard. See TextInputConnection.show.
TextInput.setEditingState: Update the value in the text editing control. The argument is a String with a JSON-encoded object with seven keys, as obtained from TextEditingValue.toJSON. See TextInputConnection.setEditingState.
TextInput.clearClient: End the current transaction. The next method called must be
TextInput.hide). See TextInputConnection.close.
TextInput.hide: Hide the keyboard. Unlike the other methods, this can be called at any time. See TextInputConnection.close.
The following incoming methods are defined for this channel (registered using MethodChannel.setMethodCallHandler). In each case, the first argument is a transaction identifier. Calls for stale transactions should be ignored.
TextInputClient.updateEditingState: The user has changed the contents of the text control. The second argument is an object with seven keys, in the form expected by TextEditingValue.fromJSON.
TextInputClient.updateEditingStateWithTag: One or more text controls were autofilled by the platform's autofill service. The first argument (the client ID) is ignored, the second argument is a map of tags to objects in the form expected by TextEditingValue.fromJSON. See AutofillScope.getAutofillClient for details on the interpretation of the tag.
TextInputClient.performAction: The user has triggered an action. The second argument is a String consisting of the stringification of one of the values of the TextInputAction enum.
TextInputClient.requestExistingInputState: The embedding may have lost its internal state about the current editing client, if there is one. The framework should call
TextInput.setEditingStateagain with its most recent information. If there is no existing state on the framework side, the call should fizzle. (This call is made without a client ID; indeed, without any arguments at all.)
TextInputClient.onConnectionClosed: The text input connection closed on the platform side. For example the application is moved to background or used closed the virtual keyboard. This method informs TextInputClient to clear connection and finalize editing.
TextInput.hideis not called after clearing the connection since on the platform side the connection is already finalized.
Calls to methods that are not implemented on the shell side are ignored (so it is safe to call methods when the relevant plugin might be missing).
static const MethodChannel textInput = OptionalMethodChannel( 'flutter/textinput', JSONMethodCodec(), );