在Fragment
中的OnCreateView
上,我将焦点侦听器附加到EditText
。如果EditText
获得焦点,则会通知侦听器。到目前为止还不错,但在屏幕旋转后,当焦点恢复到新的Fragment
上时,听众会再次收到通知。有什么好的做法可以区分由于配置更改引起的侦听器通知和由于真实的人机交互引起的侦听程序通知吗?或者在由于配置更改而导致焦点更改后,根本不通知侦听器?
问题很可能与onViewStateRestored
调用中恢复的焦点状态有关:https://developer.android.com/reference/android/app/Fragment.html#onViewStateRestored(android.os.Bundle(
为了避免监听此更改,只需在onStart
中调用setOnFocusChangeListener
,而不是onCreateView
。
onStart
是在onViewStateRestored
之后调用的,因此侦听器将不会得到初始通知。
在我回答这个问题之前,有几点需要澄清。让我们一步一步来做:
如果EditText获得焦点,则会通知侦听器。
focusListener监听获得焦点和失去焦点。
editText.setOnFocusChangeListener { view, hasFocus ->
if (hasFocus) toast("focus gained") else toast("focus lost")
}
您可以使用hasFocus布尔值来决定如何处理每个案例。
在屏幕旋转后再次通知侦听器
是否收到了获得焦点或失去焦点的通知?
当焦点恢复到新的片段上时
EditText在屏幕旋转后是对焦还是失焦?
区分由于一个配置的改变和由于一个真实的人类互动?
您可以尝试使用此官方指南来保存状态,并用于配置更改。您可以在Bundle中保存一些布尔值runCodeInListener=false。在重新创建片段或活动期间获取此布尔值。之后修改监听器内部的代码:
editText.setOnFocusChangeListener {view, hasFocus ->
if (runCodeInListener) {
if (hasFocus) toast("focus gained") else toast("focus lost")
} else {
runCodeInListener = true
}
}
在重新创建之后,当EditText的焦点第一次更改时,监听器将不会运行代码,
或者在由于配置更改而导致焦点更改后根本不通知侦听器?
Listener仅在EditText的焦点发生更改时调用。如果我们阻止上述更改,侦听器将不会收到通知。您认为此更改是由于配置更改而发生的:是因为配置更改而导致的焦点更改吗然而,还有一点需要澄清。当这个片段第一次创建时,EditText有焦点吗?如果是,则它是布局中的第一个可聚焦视图,在配置更改后,它将再次获得焦点。
在布局中创建另一个EditText,在上面设置一些新的侦听器,看看这个侦听器是否也在屏幕旋转后被调用。若我的答案是正确的,第二个EditText的监听器就不应该得到通知,因为只有第一个可聚焦的EditText才应该有焦点。为了防止EditText获得焦点,您也可以使用此或此
这需要一些编辑,所以如果有什么不清楚的地方,请询问。
需要使用onResume()
。onStart()
在视图恢复之前被调用,因此在此处注册的侦听器将被激发。