focusableInTouchMode has odd side-effects


In my application I display a table containing CheckBox-, Button- and EditText-widgets.
I would like to be able to navigate that table using the onscreen-keyboard's cursor-keys.

To be able to properly move the focus between the cells of that table I have to set

	...
	android:focusableInTouchMode="true"
	...

However, that has the odd side-effect that clicking onto a checkbox or button first only selects that widget and only the second click then actually toggles the checkbox (or clicks the button).

On the other hand, if I set android:focusableInTouchMode="false" then the checkbox toggles (or buttons react) on the first click but when I walk through the table using cursor key and the focus reaches a button or button then suddenly a different (completely off and apparently totally arbitrary) widget gets focused instead. It seems that with android:focusableInTouchMode="false" checkboxes and buttons cannot receive the focus and the system then simply picks some different widget at random.

Is this working as designed? What's could be the rationale behind that?

Or can one somehow have "click-event-on-first-click" and "focusability-via-cursor" at the same time for a CheckBox?

0
Oct 5 at 9:52 PM
User Avatarmmo
#android

Accepted Answer

Yeah, it's Android's touch mode. A tap on a view that's focusable in touch mode only gives it focus, which is meant for text fields. In touch mode, only those views can take focus, and arrow keys from the on-screen keyboard keep you in touch mode, so your buttons and checkboxes get skipped.

To get both, set focusableInTouchMode="false" and leave touch mode when an arrow key is pressed.


override fun dispatchKeyEvent(event: KeyEvent): Boolean {
    if (event.action == KeyEvent.ACTION_DOWN && window.decorView.isInTouchMode) {
        when (event.keyCode) {
            KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_DOWN,
            KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_RIGHT ->
                currentFocus?.requestFocusFromTouch() // leaves touch mode, focus stays put
        }
    }
    return super.dispatchKeyEvent(event)
}
User AvatarEmmanuel Obiechina Ikenna
Oct 6 at 12:33 AM
1