4

I was trying to set the focusability of a component and found these two methods, hoping I could use them to make the component only focusable when the user touches it, not when requested programmatically:

myComponent.setFocusable(false);
myComponent.setFocusableInTouchMode(true);

Then I looked at their documentation:

public void setFocusable (boolean focusable)

Set whether this view can receive the focus. Setting this to false will also ensure that this view is not focusable in touch mode.


public void setFocusableInTouchMode (boolean focusableInTouchMode)

Set whether this view can receive focus while in touch mode. Setting this to true will also ensure that this view is focusable.

So, if calling either one implicitly calls the other, why make the distinction?

Ky -
  • 30,724
  • 51
  • 192
  • 308
  • Related Google Code issue: https://code.google.com/p/android/issues/detail?id=152822 – Ky - Feb 20 '15 at 20:28

3 Answers3

5

There are two flags in the view system: FOCUSABLE and FOCUSABLE_IN_TOUCH_MODE. Each method sets/clears its respective flag, and there are two cases where one method affects the state of the other:

  1. Calling setFocusableInTouchMode(true) will ensure that the FOCUSABLE flag is set.
  2. Calling setFocusable(false) will ensure that the FOCUSABLE_IN_TOUCH_MODE flag is cleared.

In other words, FOCUSABLE_IN_TOUCH_MODE depends on the global FOCUSABLE flag, and cannot be set without it.

The distinction in mode is a bit legacy. The idea was to distinguish between when the user was navigating the UI with a D-pad or trackball versus tapping on a touch screen. These days, devices are pretty much always in "touch mode", but there are still a few cases where the underlying FOCUSABLE flag is checked. Mainly when hunting for the "next" view from an input method's return key or when accessibility is turned on.

For more details on the different modes, you can read the "Focus Handling" and "Touch Mode" sections of the SDK View Documentation.

devunwired
  • 62,780
  • 12
  • 127
  • 139
  • Fascinating... is there any way to enable the behavior I want? (focusable ONLY by the user touching the element) – Ky - Feb 19 '15 at 18:20
3

It is not always calling each other. Imagine having a view that is focusable with a keyboard and not focusable with touch events:

setFocusable(true);
setFocusableInTouchMode(false);
ByteHamster
  • 4,884
  • 9
  • 38
  • 53
  • This seems like strange behavior, and it's hard for me to imagine such a component. Do you know the reasoning behind this? – Ky - Feb 19 '15 at 16:18
  • 1
    The functions were added in API level 1. Back then, Android was primarily controlled by using hardware keys. Maybe it was needed once but today, I can't imagine any use-case. – ByteHamster Feb 19 '15 at 16:23
2

Note that calling setFocusable(true) won't call setFocusableInTouchMode(true) and calling setFocusableInTouchMode(false) won't call setFocusable(false). It's not equality.

Zielony
  • 16,239
  • 6
  • 34
  • 39