我有一个活动与两个EditText
s。我在第二个EditText
字段上拨打requestFocus
,因为默认情况下焦点会转到第一个。焦点似乎在第二个字段中(第二个字段获得突出显示的边框),但如果我们尝试使用硬件键盘输入任何字符,则文本会出现在第一个控件中。任何想法为什么会发生?与多个EditTexts的焦点问题
回答
尝试使用requestFocus(); http://developer.android.com/reference/android/view/View.html#requestFocus()
我面临同样的问题,我的EditText中的一个具有OnFocusListener,当它失去焦点我做一些转换,但如果出现问题,我再次试着requestFocus的,让用户来解决这个问题。这里是问题出现的时候,我最终得到了焦点的EditText,我试图用焦点搜索视图,但findFocus()返回null。我发现的唯一的解决方案是创建一个可变的EditText
private EditText requestFocus;
如果有任何问题,我在我的EditText设置为可变的,这里是我不喜欢,但它的作品,我设置OnFocusListener其他意见我的活动。当他们获得焦点,我这样做
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus)
if(requestFocus != null){
v.clearFocus();
requestFocus.requestFocus();
requestFocus = null;
}
}
我清楚的焦点从拥有它的观点,我要求进行对焦并设置变量requestFocus的空。
我相信发生这种情况是因为在我请求焦点时,没有人关注焦点,我的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;
}
里面的私有字段一个ViewGroup中存储了当前具有焦点,如果任何一个子视图。
假设您有一个ViewGroup VG
,其中包含三个可调焦视图(例如EditTexts)A
,B
和C
。
当A
失去焦点时,您已添加OnFocusChangeListener
至A
(可能不直接,但嵌入内部某处)调用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()
在这里所做的两个重要的事情:
它了标志着
A
为不受关注。它调用你的焦点变化监听器。
在该听众中,您现在拨打B.requestFocus()
。这会导致B
被标记为有焦点,然后调用VG.requestChildFocus(B, B)
。因为我们还在我打上(1)
通话深处的值仍然A
,因此这内心的召唤看起来是这样的:
if (A != B) {
if (A != null) {
A.unFocus();
}
mFocused = B; // <-- (2)
}
这一次,调用A.unFocus()
不做任何事情,因为A
已被标记为未聚焦(否则我们在这里会有无限递归)。此外,没有任何反应将C
标记为未聚焦,这是实际上现在的重点。
现在来到(2)
,其将设置为B
。经过一些更多的东西,我们终于从电话(1)
返回,因此在(3)
的值现在设置为C
,覆盖以前的变化。
所以现在我们结束了一个inc inctent状态。 B
和C
都认为他们有重点,VG
认为C
是重点儿童。
特别,按键最终在C
,这是用户不可能将焦点切换回B
,因为B
认为它已经集中,因此不会做重点要求任何东西;最重要的是,它的确不是而是请致电VG.requestChildFocus
。
推论:由于在该调用中焦点信息不一致,所以在OnFocusChanged
处理程序中,您也不应该依赖来自hasFocus()
调用的结果。
真棒回答...我的问题有点类似于... upvoting – 2014-05-29 15:39:55
很好的答案,但你建议如何解决这个问题。只需发布消息来做到这一点? – 2014-08-29 18:07:54
@RossHambrick是的,你必须在事件处理程序之外,所以这真的是我能想到的唯一解决方案。 – balpha 2014-08-29 18:21:42
我找到了解决方案。
里面的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();
}
});
}
}
});
在我的情况下没有什么区别。 – Tomislav3008 2016-08-22 09:54:43
@ Tomislav3008你为什么不用代码显示你正在尝试的问题,然后可能是我可以帮你 – 2016-08-23 07:21:27
我设法把我的请求焦点放在focusChange处理程序之外,它是要走的路。我遇到的问题正是balpha解释的,获得了两个editText视图,两个视图都有焦点。也许我的问题是把它放在一个处理程序,而不是一个监听器,我有'((EditText)发件人).Post(新的Runnable(委托{((EditText)发件人).RequestFocus();}));'' – Tomislav3008 2016-08-24 08:56:13
请发布您的代码,以便我们可以确切地看到您在做什么。 – Harris 2011-07-18 22:20:05
没有更多的信息,这个问题不能以合理的方式回答,它已经坐了很长一段时间没有额外的信息。 – 2011-09-22 21:46:31