Android Detect To See If Fragment is Visible to User.
Kotlin is here!
Imagine that you have one activity and several fragments inside it, which you dynamically add and remove using
A few days ago in my project, I realized that I couldn't understand which fragment is currently visible to the user.
I need this because when the app receives notifications from the server, I don’t want to update fragments that are not visible now
because it consumes processor time and the UI will be less responsive.
I want updates for only currently visible fragments.
I need a method that indicates that a fragment has become visible/invisible to the user (like
Activity.onResume()), APIs that I need to handle notifications in a good way, like in this example.
I had a problem though. I can’t find method
onBecomesVisible() in Fragment API. I thought that
onResume() would be triggered, but I realized that they’re connected with Activity lifecycle.
So if Activity wasn’t paused/resumed -> this method won’t be called
First, I tried to find solutions in standard Fragment API. I had four fragments in stack one above another, and method
Fragment.getUserVisibilityHint() returned true for all of them. Funny story
My solution is to use one method for navigation and execute
Fragment.setUserVisiblityHint(boolean) every time a fragment’s
visibility has changed. It looks like the following:
The client code looks like the following:
As you can see, the main difference between this and the usual method is that I manually call
from.userVisibleHint = false to mark that the fragment is not visible to the user. Now I know which fragments are not visible to the user.
Another problem is to detect when the fragment is visible to the user. The easiest solution was to add code
to.userVisibleHint = true to the previous method, but we will not cover cases when the user clicks the back button (
To handle this case, we need to listen to back stack changes and every time it’s changed, get the current fragment and execute
fragment.userVisibleHint = true.
Code: example here.
I must say, there are some bugs where
onBackStackChangedListener is executed twice on support lib version 25.0.1.
Update to 25.4.0 version and all will be all right.
Finally, we can replace our func
onBecomesVisible() with func
setUserVisibleHint(). Example here.
Of course, to prevent destroyed fragments, and to opt out of receiving notifications, we must unsubscribe from them in method
And finally, I don’t like to call this every time, but there is not enough functionality for the library, so I just place all of this logic in class
NavigationDelegate.If you find this useful, you can use this code here.
Usage in client code here.