Problem: Fragment onResume()
in ViewPager
is fired before the fragment becomes actually visible.
For example, I have 2 fragments with
setUserVisibleHint()
gets called sometimes before onCreateView()
and sometimes after which causes trouble.
To overcome this you need to check isResumed()
as well inside setUserVisibleHint()
method. But in this case i realized setUserVisibleHint()
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 in onCreate()
and setUserVisibleHint()
:
@Override
public View onCreateView(...){
...
myUIUpdate();
...
}
....
@Override
public void setUserVisibleHint(boolean visible){
super.setUserVisibleHint(visible);
if (visible && isResumed()){
myUIUpdate();
}
}
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 and myUIUpdate()
is called. Then when you swipe to 2nd tab, myUIUpdate()
from if (visible && isResumed())
is called and as a result,myUIUpdate()
may get called twice in a second.
The other problem is !visible
in setUserVisibleHint
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:
private boolean fragmentResume=false;
private boolean fragmentVisible=false;
private boolean fragmentOnCreated=false;
...
@Override
public View onCreateView(...){
...
//Initialize variables
if (!fragmentResume && fragmentVisible){ //only when first time fragment is created
myUIUpdate();
}
...
}
@Override
public void setUserVisibleHint(boolean visible){
super.setUserVisibleHint(visible);
if (visible && isResumed()){ // only at fragment screen is resumed
fragmentResume=true;
fragmentVisible=false;
fragmentOnCreated=true;
myUIUpdate();
}else if (visible){ // only at fragment onCreated
fragmentResume=false;
fragmentVisible=true;
fragmentOnCreated=true;
}
else if(!visible && fragmentOnCreated){// only when you go out of fragment screen
fragmentVisible=false;
fragmentResume=false;
}
}
Explanation:
fragmentResume
,fragmentVisible
: Makes sure myUIUpdate()
in onCreateView()
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 when onCreate
.
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.