かなり久々にAndroidのプログラミングネタです。
EditText のバックスペースキー(KeyEvent.KEYCODE_DEL)が一部端末で効かない問題があり、原因を調べてみました。
調査のため、EditText::setOnKeyListener を仕掛けてみたのですが、そもそもバックスペースキーのイベントが飛んできていないらしい。
そこで、試しに Android 9(P) 以降で追加された addOnUnhandledKeyEventListener という、その名の通りハンドルされなかったキーイベントを検出するリスナを仕掛けてみたところ、反応がありました。
という訳で、EditText::addOnUnhandledKeyEventListener がファイアしたらdispatchKeyEventをするという雑な対処を入れてみたところ、正常に動作するようになりました。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
edit.addOnUnhandledKeyEventListener { v, event ->
v.dispatchKeyEvent(event)
true
}
}
ただし、1枚のFragment / Activityに複数のEditTextがある場合、必ずしも編集中のEditTextのOnUnhandledKeyEventListener がファイアされる訳ではないようです。どうも固定のプライオリティ順序でイベントがファイアする(まるでバグのような)仕様のようです。
という訳で、複数のEditTextがある場合、hasFocusでフォーカスを持っているEditTextに対してdispatchKeyEventをしてあげるというクソのような対処が必要になるようです。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val listener = View.OnUnhandledKeyEventListener { v, event ->
when {
edit1.hasFocus() -> {
edit1.dispatchKeyEvent(event)
true
}
edit2.hasFocus() -> {
edit2.dispatchKeyEvent(event)
true
}
else -> {
false
}
}
}
edit1.addOnUnhandledKeyEventListener(listener)
edit2.addOnUnhandledKeyEventListener(listener)
}
そもそも、何故バックスペースキーのイベント(カーソルキーのイベントなども同様)がunhandledになってしまったのかが少し気になるところなので、View::addOnUnhandledKeyEventListenerのドキュメンを確認してみましたが、有益な情報は記述されていないようです。たぶん、Pieで実装された何かしらのOSのエンハンスに引っ張られてunhandledなイベントをアプリ側で捕捉しなければならない何らかのアレが起こったのであろう...と想像。
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。