Android. Detect if fragment is visible to user.
Kotlin is here)
Imagine that you have one activity and several fragments inside it, which you dynamically add, remove using
Few days ago in my project I realized that I can’t understand which fragment is currently visible to user. I need this because when app received notification from server I don’t want update fragments that are not visible now
because it consumes processor time and UI will be less responsive. I want update only currently visible fragment.
So I need method that indicates that fragment become visible/invisible to user (lke
Api that I need to handle notification in good way:
So I have this problem: I can’t find a method
onBecomesVisible() in Fragment API. I thought that
onResume() will triggered but I realized that they’re connected with Activity lifecycle. So Activity wasn’t paused/resume -> this method’s won’t be called :(
First of all I tried to find solution in standard Fragment API. I had 4 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 fragment’s
visibility changed. It looks like the following:
The client code looks like the following:
As you can see the main difference between usual method is that I manually cal
from.userVisibleHint = false to mark that fragment is not visible to user. Now I know which fragments are not visible to user.
Another problem is to detect when fragment is visible to user. The easiest solution was to add code
to.userVisibleHint = true to previous method but we will not cover case when user click back button (
popBackStack() executes). To handle this case we need to listen to back stack changes and every time it’s changed get current fragment and execute
`fragment.userVisibleHint = true`.
I must say that have some bug that
onBackStackChangedListener 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
Of course need to say to prevent destroyed fragment not to receive notification we must unsubscribe from them in method
And finally, I don’t like this call every time, but this is not enough functional for library so I just placed all this logic in class
NavigationDelegate. So if you find this useful you can use this code.
Usage in client code: