In my application, I have a ViewPager which holds many swipeable Tabs with Fragments inside. Is there a method like onResume which is called every time the fragment comes to the screen? onResume, onCreateView and so on are called after the Fragment is created and not if it comes to the screen, so they do not work for me. Which method can I use for my problem?
You can use setUserVisibleHint method in your fragment:
#Override
public void setUserVisibleHint(boolean isVisibleToUser){
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser){
// Your fragment is visible
}
}
Related
I have 10 tabs in my activity. As soon as I open the activity the first fragment gets displayed but the method (AsyncTask) present in the next fragment gets called. And if I go to the next tab say 3rd tab then the method present in the 4th fragment gets called and so on.
I don't understand this behavior. Please help!
You must know how the viewPager works populating the fragment in the different positions
When you start on the position 0, then the fragment on the position 0 and the one of the position 1 are created.
Then when you swipe to the position 1 the fragment on the 2 position is created, so you have now the three fragments created on the different positions (0,1,2..assuming you have only 3 pages on the viewPager).
We swipe to the position 2, the last one, and the fragment on the first position (0) get destroy, so we have now the fragments on the positions 2 and 3.
This is how Fragment LifeCycle Works
you can set mViewPager.setOffscreenPageLimit(2); // 2 is just an example to limit it
If you want some code to execute when Fragment become Visible to User add part of code in setUserVisibleHint method
By default it is viewpager.setOffscreenPageLimit(1) , meaning View pager will by default load atleast 1 on the right and one on the left tab of current tab.
It is done so, mostly because there is a point when you slide viewpager, when certain area of both tabs is visible. For those smooth transitions preloading is required.
You cannot set it viewpager.setOffscreenPageLimit(0).
The only way out is to use this method setUserVisibleHint
add this to your fragment
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// load data here
}else{
// fragment is no longer visible
}
}
This will be called only when that particular tab is visible to user, so only then you can call all loading function.
check sample example
Put your AsyncTask method inside this.
You can override setMenuVisibility like this:
#Override
public void setMenuVisibility(final boolean visible) {
if (visible) {
//execute AsyncTask method
}
super.setMenuVisibility(visible);
}
Happy coding!!
Override below method and move your code for Aync task into this instead of onStart() or onCreateView.
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// Load your data here or do network operations here
isFragmentLoaded = true;
}
}
see my application view here
I have 3 Fragments that I switch between with three Toolbar buttons. When I go from 1st fragment to 2nd fragment onPause() or onStop() methods are not called and android sees that fragment as still running I guess, but when I go from 1st fragment to 3rd, they are called. I want it to be called when I go from 1st to 2nd one, so I can call onResume() function when I go back to 1st fragment, so I can trigger some functions. What causes it and how can I solve?
Fragment's LifeCycle methods( onPause() and onStop() etc.) Dependent on Activity's Life cycle Methods.
It means if your Activity's onPause() and onStop() called then your fragment's onPause() and onStop() will be called
If you want to notify your fragment that it is visible or not then you can use.
Override this method in your fragments.
#Override
public void setUserVisibleHint(boolean isVisibleToUser)
{
super.setUserVisibleHint(isVisibleToUser);
if (visible)
{
// Control will be here if fragment is visible.
//Do whatever you want.
}
}
These are fragments inside ViewPager. so, on stop or onpause wont call
there is a interface in fragment named as
#Override
public void setMenuVisibility(final boolean visible) {
super.setMenuVisibility(visible);
if (visible) {
// ...
}
}
using this method u can get to know the visibility of fragment
else you can use the setOffscreenPageLimit(value);
example
mViewPager.setOffscreenPageLimit(1);
I have a ViewPager using a TabLayout. I am changing pages within a fragment of ViewPager via parentActivity.setCurrentItem() which directs to a sibling Fragment.
Only when I redirect to this fragment from a sibling I would like to display a different view. I am having a issue since the fragment is being cached and OnCreateView is not firing when the fragment is being displayed.
Is there an event that gets fired when a cached fragment is displayed?
Overriding setUserVisible(boolean isVisibleToUser) in the fragment seems to do the trick. This is triggered when the fragment is created and whenever the fragment is displayed.
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
ParentActivity parent = (ParentActivity)getActivity();
if (parent != null){
String leftMenuToShow = parent.getMenuItemToShowInFragment();
String elementToShow = parent.getElementToShowInFragment();
}
}
I'm using viewPager to create a layout with tabs and in each tab I use a Fragment. One of them is to get all de user contacts and put it on a ListView. But I want to call de AssyncTask only if the Fragment is displayed on screen.
is there a method to do it?
TY
Start your AsyncTask in onStart which is the method called once the fragment becomes visible to the user. onCreateView will be called even if the fragment doesn't become visible.
See also: http://developer.android.com/reference/android/app/Fragment.html#onStart()
I would however recommend to use a loader instead of AsyncTask (e.g. an AsyncTaskLoader http://developer.android.com/reference/android/content/AsyncTaskLoader.html).
you can use
#Override
public void setUserVisibleHint(boolean isVisibleToUser)
{
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser)
{
//things to do when fragment is visible
}
}
Even it is called before onCreateView.
You can check to see if it's visible with .isVisible() something like this
MyFragmentClass fragment = (MyFragmentClass) getSupportFragmentManager().findFragmentByTag("fragmentTAG");
if (fragment != null && fragment.isVisible()) {
// call AsyncTask
}
Thats a big problem for me right now because i need to call a method from an interface
all my fragments in my viewpager are implementing. I need to do something like this:
#Override
public void onPageSelected(int position) {
this.getActivity().getActionBar().setSelectedNavigationItem(position);
FragmentVisible fragment = (FragmentVisible) this.fragmentPager.instantiateItem(this.viewPager, position);
if (fragment != null) {
fragment.fragmentBecameVisible();
}
}
This works for the "normal startup" but when i rotate the screen i get nullpointer exceptions
because onPageSelected gets called before onViewCreated. I need my views to get updated everytime
a fragment gets visible. First i hoped onResume would get called everytime but it doesnt. For that
i implemented the interface:
public interface FragmentVisible {
public void fragmentBecameVisible();
}
Does someone has an idea how to solve this?
Per the FragmentPagerAdapter's setPrimaryItem() method (called when the ViewPager sets the current page), it calls setUserVisibleHint(true) for the current page's fragment. You can override that method in your Fragment and do your fragmentBecameVisible() method in there.