How to change ViewPager's page?
Asked Answered
W

5

151

I'm using ViewPager in my app and define it in the main Activity. Inside onCreate method I load some number of pages from SharedPreferences and then pass it to PagerAdapter:

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

The problem is that if I would change this number in Preferences (or another Activity) to some other less then page index I viewed before, my app crashes because this index is out of bounds when I return to the activity with this ViewPager. It can be fixed simply by changing active ViewPager's page. Is there any way to do it?

Windowsill answered 15/9, 2011 at 0:25 Comment(0)
K
397

I'm not sure that I fully understand the question, but from the title of your question, I'm guessing that what you're looking for is pager.setCurrentItem( num ). That allows you to programatically switch to another page within the ViewPager.

I'd need to see a stack trace from logcat to be more specific if this is not the problem.

Kirima answered 16/9, 2011 at 14:40 Comment(4)
Yes, that's exactly what I need. I set it to 0 in onPause method and there is no crashes. Thanks.Windowsill
There is indeed very less documentation on ViewPager. +1 for that.Extender
if your pager take lot time for load the page than you can use setOffscreenPageLimit(1),because by default view pager load +1 and -1 page from the current positionExmoor
This does not work I just get an error saying that the fragment has already been added.Cockpit
C
26

slide to right

viewPager.arrowScroll(View.FOCUS_RIGHT);

slide to left

viewPager.arrowScroll(View.FOCUS_LEFT);

Camilia answered 6/3, 2017 at 2:26 Comment(2)
short and clean!Crossgrained
I almost believe that this should be the accepted answer. It's much more practical than setting the current item.Piston
L
19

Without checking your code, I think what you are describing is that your pages are out of sync and you have stale data.

You say you are changing the number of pages, then crashing because you are accessing the old set of pages. This sounds to me like you are not calling pageAdapter.notifyDataSetChanged() after changing your data.

When your viewPager is showing page 3 of a set of 10 pages, and you change to a set with only 5, then call notifyDataSetChanged(), what you'll find is you are now viewing page 3 of the new set. If you were previously viewing page 8 of the old set, after putting in the new set and calling notifyDataSetChanged() you will find you are now viewing the last page of the new set without crashing.

If you simply change your current page, you may just be masking the problem.

Laundry answered 26/1, 2014 at 23:15 Comment(2)
plus 1 for notifyDataSetChanged()Imperception
@Richard You save my day buddy. 10000+ for notifyDataSetChanged()Commentative
S
18

for switch to another page, try with this code:

viewPager.postDelayed(new Runnable()
{
    @Override
    public void run()
    {
        viewPager.setCurrentItem(num, true);
    }
}, 100);
Stomatal answered 15/9, 2016 at 21:5 Comment(3)
Perfect! I tried to use it without the postDelay method and it did not work. Do you know why it works with this method? Thanks! :)Hayseed
Same question... why is the item changing with this delay and not otherwise?Pyemia
@GeorgiKoemdzhiev Because view is not finished yet when you are calling viewPager.setCurrentItemTreulich
C
3

Supplemental answer

I was originally having trouble getting a reference to the ViewPager from other class methods because the addOnTabSelectedListener made an anonymous inner class, which in turn required the ViewPager variable to be declared final. The solution was to use a class member variable and not use the anonymous inner class.

public class MainActivity extends AppCompatActivity {

    TabLayout tabLayout;
    ViewPager viewPager;

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

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

        tabLayout = (TabLayout) findViewById(R.id.tab_layout);
        tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
        tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
        tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

        viewPager = (ViewPager) findViewById(R.id.pager);
        final PagerAdapter adapter = new PagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
        viewPager.setAdapter(adapter);
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));

        // don't use an anonymous inner class here
        tabLayout.addOnTabSelectedListener(tabListener);

    }

    TabLayout.OnTabSelectedListener tabListener = 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) {

        }
    };

    // The view pager can now be accessed here, too.
    public void someMethod() {
        viewPager.setCurrentItem(0);
    }

}
Coverdale answered 5/12, 2016 at 5:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.