Search code examples
androidandroid-fragmentsandroid-actionbar-compat

Appcompat ActionBar Tab having Fragment Issue


public static class SectionsPagerAdapter extends FragmentPagerAdapter {

    public SectionsPagerAdapter(FragmentManager fm, HomeActivity activity) {
        super(fm);
    }

    @Override
    public Fragment getItem(int i) {
        switch (i) {
            case 0:
                return new FragmentOne();
            case 1:
                return new FragmentTwo();
            case 2:
                return new FragmentThree();

            default:
                return null;
        }
    }

    @Override
    public int getCount() {
        return 3;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) 
        {
            case 0 : return "Fragment 1";
            case 1 : return "Fragment 2";
            case 2 : return "Fragment 3";
            //TODO
            default : return "";
        }
    }
}

The above is the adapter for view pager. The problem is :

when clicking Tab 1, onResume() of FragmentOne and FragmentTwo get called.
going Tab1 to Tab 2, onResume() of FragmentThree called.
going Tab2 to Tab 3, onPause() of FragmentOne called.
going Tab3 to Tab 2, onResume() of FragmentOne called.

Why all the Fragments are called in this way?


Solution

  • The answer is in the way how ViewPager works. By default it stores three fragments: the one which is shown currently, one previous and one next (if present). If you want to prevent Pager from loading extra Fragments you may call its method setOffscreenPageLimit(0), but actually I wouldn't recommend doing it. So it is not an issue it is working in a way it is intended to work.

    UPD: By the way if you want to make your Pager more memory efficient, you may use FragmentStatePagerAdapter instead of FragmentAdapter, it actually destroys fragments instead of simply detaching them.

    UDP2: I'm terribly sorry but offscreenPageLimit can be not fewer than 1. So in your case since your Fragment shows a ProgressDialog it passes its host Activity as context. That's why ProgressDialog shows up when adjacent Fragment is shown. So in onResume() method of your Fragment you should check UservisibleHint of the Fragment in order to check if this is the Fragment, shown to user. If it is true then show dialog if not, then dismiss it. Like this:

    @Override
    public void onResume() {
        super.onResume();
        if (getUserVisibleHint()) {
            progressDialog = ProgressDialog.show(getActivity(), "blah-blah-blah", "blah-blah-blah");
        }
        else {
            if (progressDialog != null && progressDialog.isShowing()) progressDialog.dismiss();
        }
    }