I am attaching a focus listener to an EditText
during on OnCreateView
in my Fragment
.
If the EditText
gets focus, the listener is notified. So far so good, but the listener is notified again after screen rotation, when the focus is restored on the new Fragment
. Any good practice to distinguish between listener notification due to a configuration change and due to a real human interaction? Or to prevent the listener from being notified at all after a focus change due to a configuration change?

- 15,347
- 38
- 147
- 270
-
if the answer was helpful mark it as approved – Oleg Ushakov Apr 04 '20 at 17:10
-
1done :-) 7 more characters to go – stefan.at.kotlin Apr 04 '20 at 19:23
3 Answers
The problem is most probably related to the focus state being restored in onViewStateRestored
call:
https://developer.android.com/reference/android/app/Fragment.html#onViewStateRestored(android.os.Bundle)
To avoid listening on this change just call setOnFocusChangeListener
in onStart
instead of onCreateView
.
onStart
is called after onViewStateRestored
so the listener will not get the initial notification.

- 8,686
- 2
- 27
- 45
There are several points that need clarification before I can answer the question. Let's do this step by step:
If the EditText gets focus, the listener is notified.
focusListener listens to both gaining focus and losing it.
editText.setOnFocusChangeListener { view, hasFocus ->
if (hasFocus) toast("focus gained") else toast("focus lost")
}
You can decide by using hasFocus boolean what to do with each case.
the listener is notified again after screen rotation
Is it notified about gaining focus or losing it?
when the focus is restored on the new Fragment
Does the EditText gain or lose focus after screen rotation?
Any good practice to distinguish between listener notification due to a configuration change and due to a real human interaction?
You can try using this official guide for saving state and this for configuration changes. You can save some boolean runCodeInListener = false in the Bundle. Get this boolean during recreation of fragment or activity. After that modify the code inside the listener:
editText.setOnFocusChangeListener {view, hasFocus ->
if (runCodeInListener) {
if (hasFocus) toast("focus gained") else toast("focus lost")
} else {
runCodeInListener = true
}
}
After recreation the listener won't run the code when focus of the EditText is changed the first time,
Or to prevent the listener from being notified at all after a focus change due to a configuration change?
Listener is only invoked if focus of the EditText changes. If we prevent aforementioned change, listener won't be notified. You presume that this change occurs because of configuration change: a focus change due to a configuration change? However, there is one more point to clarify. When this fragment is created for the first time, does the EditText have focus then? If it does, then it is the first focusable view in the layout and after configuration change it gains focus again.
Create another EditText in the layout, set some new listener on it and see if this one also gets called after the screen rotation. If my answer is correct, listener of second EditText should not get notified, since only the first focusable EditText should have focus. In order to prevent EditText from gaining focus you can also use this or this
This needs some editing so if something is not clear please ask.

- 225
- 1
- 4
- 13
One needs to use onResume()
. onStart()
is called before the view restoration, so a listener registered here will fire.

- 15,347
- 38
- 147
- 270