public class KeyboardManager extends Object
KeyEvent
s dispatched to a FlutterView
, either from a hardware
keyboard or an IME event.
A class that sends Android KeyEvent
to the a list of KeyboardManager.Responder
s, and re-dispatches those not handled by the primary responders.
Flutter uses asynchronous event handling to avoid blocking the UI thread, but Android requires that events are handled synchronously. So, when the Android system sends new @{link KeyEvent} to Flutter, Flutter responds synchronously that the key has been handled so that it won't propagate to other components. It then uses "delayed event synthesis", where it sends the event to the framework, and if the framework responds that it has not handled the event, then this class synthesizes a new event to send to Android, without handling it this time.
A new KeyEvent
sent to a KeyboardManager
can be propagated to 3 different
types of responders (in the listed order):
KeyboardManager.Responder
s: An immutable list of key responders in a KeyboardManager
that each implements the KeyboardManager.Responder
interface. A
KeyboardManager.Responder
is a key responder that's capable of handling KeyEvent
s asynchronously.
When a new KeyEvent
is received, KeyboardManager
calls the KeyboardManager.Responder.handleEvent(KeyEvent, OnKeyEventHandledCallback)
method on its
KeyboardManager.Responder
s. Each KeyboardManager.Responder
must call the
supplied KeyboardManager.Responder.OnKeyEventHandledCallback
exactly once, when it has decided whether to
handle the key event callback. More than one KeyboardManager.Responder
is allowed
to reply true and handle the same KeyEvent
.
Typically a KeyboardManager
uses a KeyChannelResponder
as its only
KeyboardManager.Responder
.
TextInputPlugin
: if every KeyboardManager.Responder
has replied false to a
KeyEvent
, or if the KeyboardManager
has zero KeyboardManager.Responder
s, the KeyEvent
will be sent to the currently focused
editable text field in TextInputPlugin
, if any.
TextInputPlugin
,
or the text field does not handle the KeyEvent
either, the KeyEvent
will be
sent back to the top of the activity's view hierachy, allowing it to be "redispatched",
only this time the KeyboardManager
will not try to handle the redispatched KeyEvent
.
Modifier and Type | Field and Description |
---|---|
protected io.flutter.embedding.android.KeyboardManager.Responder[] |
responders |
Constructor and Description |
---|
KeyboardManager(View view,
TextInputPlugin textInputPlugin,
io.flutter.embedding.android.KeyboardManager.Responder[] responders)
Constructor for
KeyboardManager that takes a list of KeyboardManager.Responder s. |
@NonNull protected final io.flutter.embedding.android.KeyboardManager.Responder[] responders
public KeyboardManager(View view, @NonNull TextInputPlugin textInputPlugin, io.flutter.embedding.android.KeyboardManager.Responder[] responders)
KeyboardManager
that takes a list of KeyboardManager.Responder
s.
The view is used as the destination to send the synthesized key to. This means that the the
next thing in the focus chain will get the event when the KeyboardManager.Responder
s
return false from onKeyDown/onKeyUp.
It is possible that that in the middle of the async round trip, the focus chain could change, and instead of the native widget that was "next" when the event was fired getting the event, it may be the next widget when the event is synthesized that gets it. In practice, this shouldn't be a huge problem, as this is an unlikely occurrence to happen without user input, and it may actually be desired behavior, but it is possible.
view
- takes the activity to use for re-dispatching of events that were not handled by the
framework.textInputPlugin
- a plugin, which, if set, is given key events before the framework is,
and if it has a valid input connection and is accepting text, then it will handle the event
and the framework will not receive it.responders
- the KeyboardManager.Responder
s new KeyEvent
s will be first
dispatched to.public boolean handleEvent(@NonNull KeyEvent keyEvent)
public void destroy()