clearFocus() 和 focusableInTouchMode="true" 如何协同工作?

How do clearFocus() and focusableInTouchMode="true" work together?

我希望有人能解释以下两种行为。

我从这个屏幕开始:

当我触摸 "City You're From" 内的文本区域时,我得到以下屏幕:

当我按下键盘的 "Done" 按钮时,我按预期返回了原始状态。换句话说,隐藏框再次可见并且光标消失(EditText 不再具有焦点)。发生这种情况的原因是我只有一个监听器在等待 "Done" 按钮被按下。当发生这种情况时,我在 EditText 视图上调用 clearFocus()。然后我有一个 OnFocusChangeListener 使所有框 invisible/visible 取决于 EditText 是否有焦点。

但是,当我使用以下 属性 设置祖先布局(即 parent 或 grandparent RelativeLayout)时,我只会得到这种预期的行为:android:focusableInTouchMode="true"

否则,我会看到以下屏幕:

当调用 clearFocus() 时,它会跳到层次结构中的下一个 child,即 "Current City" 并给予 EditText 焦点(并隐藏键盘但这是预期行为的一部分)。

如果我没有设置 android:focusableInTouchMode="true",则在屏幕 1 中单击 "Current City" 也会出现屏幕 3。换句话说,它保持在 "Current City" 并且不会失去焦点。

问题 有人可以解释这是怎么回事吗?为什么遗漏 android:focusableInTouchMode="true" 会导致这种奇怪的行为?

我在 source code 上面的评论中找到了 clearFocus():

的答案

”当此视图想要放弃焦点时调用。如果焦点被清除,则调用 onFocusChanged(boolean,int,android.graphics.Rect)。 注意:当视图清除焦点时,框架会尝试将焦点赋予顶部的第一个可聚焦视图。因此,如果此视图是从顶部开始第一个可以获得焦点的视图,那么将调用所有与清除焦点相关的回调,然后框架将焦点赋予此视图。"

换句话说,当一个视图放弃焦点时,框架从根开始向下遍历层次结构,寻找它可以给予焦点的第一个视图。当我省略 android:focusableInTouchMode="true" 时,框架将焦点提供给 "Current City",因为这是它发现的第一个可聚焦的视图。当多个事物可聚焦在层次结构的同一级别时,框架从最接近实际 xml 代码底部的视图开始。这样做的原因是因为如果 2 个视图在层次结构中处于同一级别,并且您将视图放置在屏幕上的相同位置,那么最靠近代码底部的视图将出现在屏幕顶部。