ViewPager上でEditTextなどを表示してIMEがでた状態で、特定のボタンを押すとPageが切り替わる。とゆう話。
KeyEvent
①と②の左右のArrowのアイコンのボタンは、TextViewに対して以下のようなイベントを発行する。
Event property | Value | Value |
---|---|---|
Action | KeyEvent.ACTION_DOWN |
KeyEvent.UP |
KeyCode | KeyEvent.KEYCODE_DPAD_LEFT |
KeyEvent.KEYCODE_DPAD_RIGHT |
したがって、このようにイベントをハンドリングすることができる。
binding.editText.setOnKeyListener { _, _, event ->
if (event.action != KeyEvent.ACTION_DOWN) {
return@setOnKeyListener false
}
return@setOnKeyListener when (event.keyCode) {
KeyEvent.KEYCODE_DPAD_LEFT -> {
// handle when Push left arrow icon button.
false
}
KeyEvent.KEYCODE_DPAD_RIGHT -> {
// handle when Push right arrow icon button.
false
}
else -> {
true
}
}
}
EditorAction
③の動きを取りたい場合は、 EditorActionListener
を利用する
binding.editText.setOnEditorActionListener { _, actionId, _ ->
return@setOnEditorActionListener when(actionId) {
EditorInfo.IME_ACTION_DONE -> {
// Handle when pushed done button(right bottom)
true
}
else -> {
false
}
}
}
引数は、そのイベントを他に伝播させるかどうか。true
にして伝播させると、次のFocusableなViewにFocusが行くようになる。
右下のアイコンは、よしなにしてくれる模様。
指定したい場合は、 android:imeOptions="send"
のようにする。
https://developer.android.com/reference/android/view/inputmethod/EditorInfo#imeOptions
ViewPager上で利用するときの注意点
ココでハマった...
ViewPagerは、KeyEventをInterceptして、ページの切り替えに利用している。
したがって、ViewPager上でEditTextを表示してIMEがでた状態で、 左右の①か②のボタ押下するとページが切り替わる
/**
* You can call this function yourself to have the scroll view perform
* scrolling from a key event, just as if the event had been dispatched to
* it by the view hierarchy.
*
* @param event The key event to execute.
* @return Return true if the event was handled, else false.
*/
public boolean executeKeyEvent(@NonNull KeyEvent event) {
boolean handled = false;
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_DPAD_LEFT:
if (event.hasModifiers(KeyEvent.META_ALT_ON)) {
handled = pageLeft();
} else {
handled = arrowScroll(FOCUS_LEFT);
}
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
if (event.hasModifiers(KeyEvent.META_ALT_ON)) {
handled = pageRight();
} else {
handled = arrowScroll(FOCUS_RIGHT);
}
break;
case KeyEvent.KEYCODE_TAB:
if (event.hasNoModifiers()) {
handled = arrowScroll(FOCUS_FORWARD);
} else if (event.hasModifiers(KeyEvent.META_SHIFT_ON)) {
handled = arrowScroll(FOCUS_BACKWARD);
}
break;
}
}
return handled;
}
切り替えたくない場合は、 setOnKeyListener
の返り値をfalseにして伝播させないようにする。