Problem: Fragment onResume()
in ViewPager
is fired before the fragment becomes actually visible.
For example, I have 2 fragments with ViewPager
and FragmentPagerAdapter
. The second fragment is only available for authorized users and I need to ask the user to log in when the fragment becomes visible (using an alert dialog).
BUT the ViewPager
creates the second fragment when the first is visible in order to cache the second fragment and makes it visible when the user starts swiping.
So the onResume()
event is fired in the second fragment long before it becomes visible. That's why I'm trying to find an event which fires when the second fragment becomes visible to show a dialog at the appropriate moment.
How can this be done?
Note that
setUserVisibleHint(false)
is not called on activity / fragment stop. You'll still need to check start/stop to properlyregister/unregister
any listeners/etc.Also, you'll get
setUserVisibleHint(false)
if your fragment starts in a non-visible state; you don't want tounregister
there since you've never registered before in that case.Override
Fragment.onHiddenChanged()
for that.I figured out that
onCreateOptionsMenu
andonPrepareOptionsMenu
methods called only in the case of the fragment really visible. I could not found any method which behaves like these, also I triedOnPageChangeListener
but it did not work for the situations, for example, I need a variable initialized inonCreate
method.So these two methods can be used for this problem as a workaround, specifically for little and short jobs.
I think, this is the better solution but not the best. I will use this but wait for better solution at the same time.
Regards.
setUserVisibleHint()
gets called sometimes beforeonCreateView()
and sometimes after which causes trouble.To overcome this you need to check
isResumed()
as well insidesetUserVisibleHint()
method. But in this case i realizedsetUserVisibleHint()
gets called only if Fragment is resumed and visible, NOT when Created.So if you want to update something when Fragment is
visible
, put your update function both inonCreate()
andsetUserVisibleHint()
:UPDATE: Still i realized
myUIUpdate()
gets called twice sometimes, the reason is, if you have 3 tabs and this code is on 2nd tab, when you first open 1st tab, the 2nd tab is also created even it is not visible andmyUIUpdate()
is called. Then when you swipe to 2nd tab,myUIUpdate()
fromif (visible && isResumed())
is called and as a result,myUIUpdate()
may get called twice in a second.The other problem is
!visible
insetUserVisibleHint
gets called both 1) when you go out of fragment screen and 2) before it is created, when you switch to fragment screen first time.Solution:
Explanation:
fragmentResume
,fragmentVisible
: Makes suremyUIUpdate()
inonCreateView()
is called only when fragment is created and visible, not on resume. It also solves problem when you are at 1st tab, 2nd tab is created even if it is not visible. This solves that and checks if fragment screen is visible whenonCreate
.fragmentOnCreated
: Makes sure fragment is not visible, and not called when you create fragment first time. So now this if clause only gets called when you swipe out of fragment.Update You can put all this code in
BaseFragment
code like this and override method.Another solution posted here overriding setPrimaryItem in the pageradapter by kris larson almost worked for me. But this method is called multiple times for each setup. Also I got NPE from views, etc. in the fragment as this is not ready the first few times this method is called. With the following changes this worked for me:
This seems to restore the normal
onResume()
behavior that you would expect. It plays well with pressing the home key to leave the app and then re-entering the app.onResume()
is not called twice in a row.