Anurag Rana
Anurag Rana

Reputation: 1466

Android : Tab Fragments are not getting initialized when expected

I am new to Android development. I am trying to develop an app with tab fragments.

I have three fragments. When I launch application, onCreateView method of first and second fragment is called. When fragment 2 is selected (by swiping or clicking tab) , fragment three's onCreateView is called. When fragment three is selected, nothing happens. When fragment 2 is selected again (coming from fragment 3 towards fragment 1), fragment one's onCreateView is called.

I want onCreateView of a fragment to be called when that view is visible. I am pasting the code of my project here. Please suggest me what is happening.

MainActivity

public class MainActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Toolbar and fragments ---- start ---
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
        tabLayout.addTab(tabLayout.newTab().setText("New"));
        tabLayout.addTab(tabLayout.newTab().setText("Queue"));
        tabLayout.addTab(tabLayout.newTab().setText("About"));
        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

        final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
        final PagerAdapter pagerAdapter = new PagerAdapter
                (getSupportFragmentManager(), tabLayout.getTabCount());
        viewPager.setAdapter(pagerAdapter);
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                viewPager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });


    }
}

PagerAdapter Class

public class PagerAdapter extends FragmentStatePagerAdapter {
    int mNumOfTabs;
    SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
    public PagerAdapter(FragmentManager fm, int NumOfTabs) {
        super(fm);
        this.mNumOfTabs = NumOfTabs;
    }

    @Override
    public Fragment getItem(int position) {

        switch (position) {
            case 0:
                TabFragment1 tab1 = new TabFragment1();
                return tab1;
            case 1:
                TabFragment2 tab2 = new TabFragment2();
                return tab2;
            case 2:
                TabFragment3 tab3 = new TabFragment3();
                return tab3;
            default:
                return null;
        }
    }

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

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment fragment = (Fragment) super.instantiateItem(container, position);
        registeredFragments.put(position, fragment);

        return fragment;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        registeredFragments.remove(position);
        super.destroyItem(container, position, object);
    }

    public Fragment getRegisteredFragment(int position) {
        return registeredFragments.get(position);
    }
}

Fragement (all fragments have same code only toast text changes)

public class TabFragment3 extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Toast.makeText(getActivity().getApplicationContext(),"333",Toast.LENGTH_LONG).show();
        return inflater.inflate(R.layout.tab_fragment_3, container, false);
    }
}

Upvotes: 1

Views: 1938

Answers (1)

Pavan Bilagi
Pavan Bilagi

Reputation: 1617

getItem(..) will always be called twice because it loads the current View that the user see and it always loads the next view which the user cannot see yet. This allows for smoother transitions between screens(views).

You can set the number of screens that the adapter should load by calling:

mViewpager.setOffscreenPageLimit(3);

where 3 is the number of screens to load in advance. This means that getItem will now be called five times.

The minimum number of OffScreenPages are 1, it cannot be set to 0, thus getItem(..) will always execute at least twice.

Upvotes: 3

Related Questions