Class KeyboardManager

  • public class KeyboardManager
    extends Object
    A class to process KeyEvents 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.Responders, 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.Responders: 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 KeyEvents asynchronously.

      When a new KeyEvent is received, KeyboardManager calls the KeyboardManager.Responder.handleEvent(KeyEvent, OnKeyEventHandledCallback) method on its KeyboardManager.Responders. 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.Responders, the KeyEvent will be sent to the currently focused editable text field in TextInputPlugin, if any.
    • "Redispatch": if there's no currently focused text field in 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.
    • Field Detail

      • responders

        protected final[] responders
    • Constructor Detail

      • KeyboardManager

        public KeyboardManager​(@NonNull
                               View view,
                               TextInputPlugin textInputPlugin,
                     [] responders)
        Constructor for KeyboardManager that takes a list of KeyboardManager.Responders.

        The view is used as the destination to send the synthesized key to. This means that the next thing in the focus chain will get the event when the KeyboardManager.Responders 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.Responders new KeyEvents will be first dispatched to.
    • Method Detail

      • handleEvent

        public boolean handleEvent​(@NonNull
                                   KeyEvent keyEvent)
      • destroy

        public void destroy()