在阅读了@Raj 的答案、浏览了 Android documentation 并尝试了代码之后,我想我现在了解它们如何工作得更好了。如果其他人有类似的困惑,这里有一些额外的帮助。如果我弄错了,请告诉我。
视图可以聚焦或不聚焦。有些视图在聚焦时会改变外观。这在使用键盘导航布局时特别有用。这样,您在实际单击视图之前就知道自己在哪里。 using a selector and drawables 可以使焦点不会自然改变的视图也可以这样做。但是,如果您不使用键盘进行导航,那么焦点就不是那么重要了。
有三对让我感到困惑的事情:
isFocusable()
isFocusableInTouchMode()
setFocusable()
setFocusableInTouchMode()
requestFocus()
requestFocusFromTouch()
第一对只是告诉你关于视图的信息。也就是说,该视图是否有可能被聚焦。您可以通过执行以下操作来找出答案:
Boolean b = myView.isFocusable();
您在触摸屏幕后处于触摸模式。因此,当您使用键盘时可能可以聚焦的东西在您使用手指时可能无法聚焦。你可以这样检查:
Boolean b = myView.isFocusableInTouchMode();
就像我说的,这只会告诉你是否有可能给视图焦点。如果你想真正给视图焦点,首先你必须让它成为焦点。您可以使用以下命令之一执行此操作:
myView.setFocusable(true);
myView.setFocusableInTouchMode(true);
如果您处于触摸模式并调用setFocusableInTouchMode(true),则myView.isFocusable() 和myView.isFocusableInTouchMode() 都将返回true。您无需同时调用它们。但是,如果您只调用myView.setFocusable(true),那么myView.isFocusableInTouchMode() 将不会更改。
现在要最终使视图聚焦,您必须调用以下代码:
myView.requestFocus();
我仍然不完全理解requestFocusInTouchMode(),因为仅使用requestFocus() 对我有用,但documentation 说的是requestFocusInTouchMode():
调用它以尝试将焦点放在特定视图或其后代之一上。这是 requestFocus() 的一个特殊变体,它允许在触摸模式下无法聚焦的视图在被触摸时请求焦点。
最后要注意的是Romain Guy在这个post中说的:
在触摸模式下可聚焦的视图具有奇怪的交互,除非您完全了解自己在做什么,否则不应使用它。 requestFocus() 有效,但仅在设备未处于触摸模式时才显示焦点。一旦用户触摸屏幕,就不再显示焦点。通过做你正在做的事情,你会让你的应用程序的行为与系统的其他部分不同,并且你冒着奇怪行为的风险。