0

There is 3 TabLayout with ViewPager in my application.

If I swipe for change Tabs then it behaves strangely.

Below is the scenario.

Let's say 3 Tabs A, B, C.

Default Tab A will open when I start App.

Go to B From A - Works OK.
Go to A From B - Works Ok.
Go To B From A - Works Ok.
Go To C From B - Works Ok.

Now Problem Starts here.
Go To B From C - It will Load A and B Both but display Only B.

Why A and B loads if I come from C ??

Below is my code.

private Toolbar toolbar;
    private TabLayout tabLayout;
    private ViewPager viewPager;
    ViewPagerAdapter adapter;

toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        getSupportActionBar().setDisplayHomeAsUpEnabled(false);

        viewPager = (ViewPager) findViewById(R.id.viewpager);
        setupViewPager(viewPager);
        tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(viewPager);

private void setupViewPager(ViewPager viewPager) {
        adapter = new ViewPagerAdapter(getSupportFragmentManager());
        adapter.addFragment(new FragmentOpen(), "OPEN");
        adapter.addFragment(new FragmentClose(), "CLOSE");
        adapter.addFragment(new FragmentTest(), "TEST");
        viewPager.setAdapter(adapter);
    }

    class ViewPagerAdapter extends FragmentPagerAdapter {
        private final List<Fragment> mFragmentList = new ArrayList<>();
        private final List<String> mFragmentTitleList = new ArrayList<>();

        public ViewPagerAdapter(FragmentManager manager) {
            super(manager);
        }

        @Override
        public Fragment getItem(int position) {
            return mFragmentList.get(position);
        }

        @Override
        public int getCount() {
            return mFragmentList.size();
        }

        public void addFragment(Fragment fragment, String title) {
            mFragmentList.add(fragment);
            mFragmentTitleList.add(title);
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return mFragmentTitleList.get(position);
        }
    }

I want to load Tabs every time.
For that, I use below code.

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                if(adapter != null){
                    adapter.getItem(position).onResume();
                }
                Toast.makeText(getApplicationContext(), "Page Selected", Toast.LENGTH_LONG).show();
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

But it will always load both tabs when I came from C.

What I want is: only Tab B must load when came from C, not Both.

Chirag Savsani
  • 6,020
  • 4
  • 38
  • 74

3 Answers3

1

Its not possible when using ViewPager. ViewPager loads at least one right/left adjacent fragment of current fragment as per your swipe direction.

If you read the ViewPager documentation, there is a method ViewPager.setOffscreenPageLimit(LIMIT) which supports off screen page limit and its default value is 1.

SetOffscreenPageLimit:

Set the number of pages that should be retained to either side of the current page in the view hierarchy in an idle state. Pages beyond this limit will be recreated from the adapter when needed.

This is offered as an optimization. If you know in advance the number of pages you will need to support or have lazy-loading mechanisms in place on your pages, tweaking this setting can have benefits in perceived smoothness of paging animations and interaction. If you have a small number of pages (3-4) that you can keep active all at once, less time will be spent in layout for newly created view subtrees as the user pages back and forth.

You should keep this limit low, especially if your pages have complex layouts. This setting defaults to 1.

See documentation.

Here are some related answers:

1. ViewPager.setOffscreenPageLimit(0) doesn't work as expected

2. How can make my ViewPager load only one page at a time ie setOffscreenPageLimit(0);

3. How does setOffscreenPageLimit() improve ViewPager performance by retaining more offscreen Fragments?

Community
  • 1
  • 1
Ferdous Ahamed
  • 21,438
  • 5
  • 52
  • 61
  • Can you suggest any alternatives for this? I want to prevent tabs to load. If I swipe tabs, it should not load any tabs. – Chirag Savsani Jun 08 '17 at 04:09
  • You can try with `Interface`. Write an `Interface` in your `activity` and implement it from `Fragment` classes. Add addOnPageChangeListener to viewpager and setOnTabSelectedListener to TabLayout. From those listeners implemented method call your own interface method and pass current item position with it. Then in your fragment check weather the current item is your current fragment or not and loads data otherwise do nothing. – Ferdous Ahamed Jun 08 '17 at 04:37
1

its Default behavior of ViewPager if you are in A then it loads B also and when your reach B it will Load C and A also is Loaded now when to reach at C its destroy the View of A and now when you come again to B it will Load A again, in a simple way ViewPager Maintain the One Next and One previous state of View by Default.

to Overcome this you should use ViewPager.setOffscreenPageLimit(number) here number is the count of page to load Simulationally for Next and Previous View.

Aniruddh Parihar
  • 3,072
  • 3
  • 21
  • 39
  • Can you suggest any alternatives for this? I want to prevent tabs to load. If I swipe tabs, it should not load any tabs. – Chirag Savsani Jun 08 '17 at 04:10
  • yes i can. as you mentioned you have 3 Tabs and you Don't want to load any one tab when you swiping these, so you have to set this ViewPager.setOffscreenPageLimit(3); after this viewPager.setAdapter(adapter); statement, that's it, it will not load again when you swipe tab. – Aniruddh Parihar Jun 08 '17 at 08:17
0

I had only 3 tabs and settingViewPager.setOffscreenPageLimit(2) worked for me.

Try ViewPager.setOffscreenPageLimit(totTabs - 1)

sibin
  • 107
  • 9