📘

ActionのinvokeでKeyEventResult.ignoredを返す

2024/04/14に公開

FlutterのActioninvokeはnullを返そうが、KeyEventResult.ignoredを返そうが、ショートカットとして検知されてしまうため、それ以降の親のActionやネイティブ側のショートカットが検知されなくなってしまいます。

FocusonKeyではKeyEventResult.ignoredを返せば検知されなかったことになるのですが、これをinvokeメソッドでも行う方法の記事です。

結論

toKeyEventResultをoverrideしてあげ、KeyEventResult.ignoredを返すようにしてあげるだけです。

class HogeAction extends Action<HogeIntent> {
  
  KeyEventResult toKeyEventResult(
    Intent intent,
    covariant Object? invokeResult,
  ) {
    // invokeResultがKeyEventResultの場合はそのまま返す
    if (invokeResult is KeyEventResult) {
      return invokeResult;
    }

    return super.toKeyEventResult(intent, invokeResult);
  }

  
  Object? invoke(...) {
    return KeyEventResult.ignored;
  }
}

説明

toKeyEventResultメソッドは内部コード的には以下のようになっています。
consumesKeyは必ずtrueを返すようになっているので、handledが検知されているようです。(consumesKeyはoverrideする前提だと思います)

KeyEventResult toKeyEventResult(T intent, covariant Object? invokeResult) {
    return consumesKey(intent)
      ? KeyEventResult.handled
      : KeyEventResult.skipRemainingHandlers;
  }

invokeResultinvokeメソッドの戻り値なので、これがKeyEventResultだったらその値を返すようにしてあげればinvokeKeyEventResult.ignoredを返してあげればそのアクションが未検知となります。

締め

毎回overrideをするのも面倒なので、私の個人開発のリポジトリではCustomActionというのを作っています。

https://github.com/imajoriri/quick_flutter/blob/7d1ce36c602a11d6c1e00e3b02eabbce4f98f367/lib/widget/actions/custom_action.dart#L8

Discussion