重点与多个EditText的问题

我有两个EditText的活动。 我在第二个EditText字段上调用requestFocus ,因为默认情况下焦点会转到第一个。 焦点似乎在第二个字段中(第二个字段获得突出显示的边框),但是如果我们尝试使用硬件键盘input任何字符,则文本会出现在第一个EditText控件中。 任何想法,为什么会发生?

Solutions Collecting From Web of "重点与多个EditText的问题"

很难说这是否是你的问题,但这不是不可能的。

TL; DR:永远不要在onFocusChanged()调用中调用焦点更改方法,如requestFocus()

问题在于ViewGroup.requestChildFocus() ,它包含这个:

 // We had a previous notion of who had focus. Clear it. if (mFocused != child) { if (mFocused != null) { mFocused.unFocus(); } mFocused = child; } 

在私人领域mFocused一个ViewGroup存储当前有焦点的子视图,如果有的话。

假设您有一个ViewGroup VG ,其中包含三个可聚焦视图(例如EditTexts) ABC

A失去焦点时,你可以添加一个OnFocusChangeListenerA (可能不是直接的,但嵌套在里面的某个地方)调用B.requestFocus()

现在设想A有焦点,用户点击C ,导致A失去, C获得焦点。 由于VG.mFocused当前是A ,因此VG.requestChildFocus(C, C)的上面部分转换为:

 if (A != C) { if (A != null) { A.unFocus(); // <-- (1) } mFocused = C; // <-- (3) } 

A.unFocus()在这里做了两件重要的事情:

  1. 它标志着A不再有焦点了。

  2. 它调用你的焦点变化监听器。

在那个监听器中,你现在调用B.requestFocus() 。 这导致B被标记为有焦点,然后调用VG.requestChildFocus(B, B) 。 因为我们在(1)标记的调用中仍然很深, mFocused的值仍然是A ,所以这个内部调用看起来像这样:

 if (A != B) { if (A != null) { A.unFocus(); } mFocused = B; // <-- (2) } 

这一次,对A.unFocus()的调用不做任何事情,因为A已经被标记为未聚焦(否则我们会在这里有一个无限的recursion)。 此外,没有任何反应将C标记为未聚焦,这是现在实际上已经关注的视图。

现在来(2) ,它将mFocused设置为B 在更多的东西之后,我们终于从(1)处的调用返回,因此在(3)中, mFocused的值现在被设置为C覆盖以前的改变

所以现在我们结束了一个incusiontent状态。 BC都认为他们有重点, VG认为C是重点儿童。

特别是,按键最终在C ,并且用户不可能将焦点切换回B ,因为B认为它已经具有焦点,因此对焦点请求不做任何事情; 最重要的是,它不会调用VG.requestChildFocus

推论:在OnFocusChanged处理程序中,您也不应该依赖hasFocus()调用的结果,因为在该调用中焦点信息不一致。

我find了解决scheme。

里面onFocusChange不直接调用requestFocus,而是发布一个runnable来请求焦点。 例如在我的代码下面,

 editText.setOnFocusChangeListener(new OnFocusChangeListener() { public void onFocusChange(View v, boolean hasFocus) { if (hasFocus == false) { editText.post(new Runnable() { @Override public void run() { editText.requestFocus(); } }); } } }); 

我面临同样的问题,我的EditText有一个OnFocusListener,当它失去焦点时,我做了一些转换,但如果出现问题,我尝试再次requestFocus,让用户来解决这个问题。 这是问题出现的时候,我最终得到了焦点的EditText,我试图用焦点search视图,但是findFocus()返回null。 我find的唯一解决scheme是创build一个EditTextvariables

 private EditText requestFocus; 

如果有任何问题,我把我的EditText设置为该variables,这是我不喜欢,但它的作品,我设置OnFocusListener我的活动的其他意见。 当他们获得焦点时,我这样做

 @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) if(requestFocus != null){ v.clearFocus(); requestFocus.requestFocus(); requestFocus = null; } } 

我从视图中清除了焦点,我请求焦点并设置variablesrequestFocus null。

我相信这是因为在我请求焦点的时候,没有人关注焦点,我的EditText重新获得焦点,活动将焦点放到下一个视图上。 希望有助于某人。