Gamericious Blog
Gamericious Blog

Reputation: 129

How to only call onCreateView when fragment is visible?

I'm using a ViewPager with 5 fragments and my problem is that when the first fragment is visible, it already loads the second one.

I read something about viewPager.setOffscreenPageLimit(); but default value for this is '1' and can't be set to '0' because ViewPager needs this for the swipe animation.

So the second fragment will always be loaded by default.

But my problem is that i have a global Arraylist in both fragments with different values loaded in each fragment and when i'm on fragment one, the values get overwritten because the second fragment is called.

How to only call onCreateView for each fragment when that fragment is visible for the user?

Upvotes: 0

Views: 1440

Answers (3)

Gopinath
Gopinath

Reputation: 184

View pager will load the near by fragments, even if you set setOffscreenPageLimit to 0. Since if the value is less than 1, they will set it as 1.

So onCreate, onCreateView... onResume of the near by fragments will be called before it is visible.

So just load your data in setUserVisibleHint.

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if(getView() != null && isVisibleToUser){
        loadData();
    }
}

But there exists a problem. This method(setUserVisibleHint) will be called before the onCreate of our fragment.

If you get the data from arguments.. We will get those data from onCreate or onCreateView of fragment. So the first visible fragment's setUserVisibleHint will be called, without data to load(getView() != null from the above method). For this we can use

 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = super.onCreateView(inflater,container,savedInstanceState);

    // This is because for the first fragment to loadData, since the 
    // setUserVisibleHint is called before the onCreateView of the fragment.

    if(getUserVisibleHint()){
        loadData();
    }

    return view;
}

loadData is the method which will do data binding part of my fragment.

By doing this, For the first visible fragment loadData will be called from onCreateView and near by fragment it will be called from setUserVisibleHint.

Upvotes: 0

abhi.nalavade
abhi.nalavade

Reputation: 196

By using this you can give a try,

@Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
}

Upvotes: 0

Sam
Sam

Reputation: 5392

First, I would not use a global list. Make a baseFragment if you need to hold a similar type of list. If your goal is to share filtering among fragments, then simply pass the applied filters to each fragment so it knows how to manage its list as it loads or pass the list, but don't use a global that's just asking for trouble.

Second, onCreate is called on the pager on purpose so you can preload some things before it shows on the screen. It's to improve rendering performance as the user swipes from side to side. If you load as the swipe happens, it will be jumpy and bad.

Lastly consider moving your logic to onResume, unless you have good reason not to. If that doesn't work for you, then monitor the page changing event and call a shared "load" method that you create on each baseFragment that you can simply call and handle your code there.

Upvotes: 1

Related Questions