18

What is the difference between setFocusable and setFocusableInTouchMode for an Android view?

Additional question after trying to read the documentation:

And how are these different from isFocusable and isFocusableInTouchMode?

Suragch
  • 935
  • 3
  • 9
  • 15
  • 1
    This is clearly explained in the documentation. – nhaarman May 22 '14 at 06:14
  • 13
    I often find the explanations on stack overflow easier to understand than the documentation. I'm trying to go through the documentation now, but I am having trouble understanding it. I was hoping someone here would be willing to explain and maybe give an example. – Suragch May 22 '14 at 06:31
  • 1
    I added my own answer below to explain more clearly what I didn't understand when I asked. – Suragch May 22 '14 at 09:12
  • 2
    @nhaarman Little is "clearly" explained in the documentation, which is why sites like SO exist. It has great explanations of requestLayout / invalidate and getHeight / getMeasuredHeight because the documentation tends to be vague or similar. This is clearly explained in the question. – Abandoned Cart May 08 '17 at 19:49

2 Answers2

31

setFocusable mainly used for enable/disable view's focus event on both touch mode and keypad mode( using up/down/next key).

setFocusableInTouchMode mainly used for enable/disable view's focus event on touch mode alone.

If you are disabled setFocusable it also disabled the view's focus event on touch mode.

Rajkumar Nagarajan
  • 1,091
  • 1
  • 10
  • 6
  • If I call setFocusableInTouchMode(true) do I also need to call setFocusable(true) or is that already implied? – Suragch May 22 '14 at 06:51
  • 1
    No. You can call only setFocusableInTouchMode(true), but ensure you didn't called setFocusable(false). – Rajkumar Nagarajan May 22 '14 at 07:08
  • Thanks for this. I was setting both when all I have ever needed was setFocusable. Unfortunately, it was because when finding information on explicitly setting focus, that person suggested using both (and obviously did not fully understand the difference, either). – Abandoned Cart May 08 '17 at 19:34
24

After reading the answer from @Raj, going through the Android documentation, and experimenting with the code, I think I understand how they work a little better now. Here is a little additional help if anyone else is similarly confused. Let me know if I've got it wrong.

Views can be focused or unfocused. Some views change their appearance when they are focused. This can be especially useful when using a keypad to navigate the layout. This way you know where you are before you actually click a view. Even views that do not naturally change when focus can be made to do so by using a selector and drawables. If you are not using a keypad to navigate, though, focus is not as important.

There were three pairs of things that were confusing me:

isFocusable()
isFocusableInTouchMode()

setFocusable()
setFocusableInTouchMode()

requestFocus()
requestFocusFromTouch()

The first pair just tells you information about the view. That is, whether or not it is even possible for that view to be focused. You can find out by doing something like this:

Boolean b = myView.isFocusable();

You are in touch mode after you have touched the screen. So something that may be focusable when you are using the keypad may not be focusable when you are using your fingers. You can check like this:

Boolean b = myView.isFocusableInTouchMode();

Like I said, this only tells you information about whether it is even possible to give the view focus or not. If you want to actually give the view focus, first you have to make it possible to be focused. You can do this with one of the following commands:

myView.setFocusable(true);
myView.setFocusableInTouchMode(true);

If you are in touch mode and you call setFocusableInTouchMode(true) then both myView.isFocusable() and myView.isFocusableInTouchMode() will return true. You don't need to call them both. However, if you only call myView.setFocusable(true) then myView.isFocusableInTouchMode() will not be changed.

Now to finally make the view focused you have to call the following:

myView.requestFocus();

I still don't fully understand requestFocusInTouchMode() because just using requestFocus() worked for me, but the documentation says about requestFocusInTouchMode():

Call this to try to give focus to a specific view or to one of its descendants. This is a special variant of requestFocus() that will allow views that are not focuable in touch mode to request focus when they are touched.

Finally, it should be noted that Romain Guy said in this post:

A view that's focusable in touch mode has weird interactions and unless you perfectly understand what you are doing you should NOT use it. requestFocus() works, but focus is shown only when the device is not in touch mode. As soon as the user touches the screen, the focus is not displayed anymore. By doing what you are doing you are making your app behave differently from the rest of the system and you risk weird behaviors.

Community
  • 1
  • 1
Suragch
  • 935
  • 3
  • 9
  • 15
  • 1
    This actually contradicts the accepted answer. setFocusable covers both, while setFocusableInTouchMode only covers itself. An example would be that you want the user to be able to touch an ImageView, but not select it with the keyboard, so you would use setFocusableInTouchMode. – Abandoned Cart May 08 '17 at 19:52