44

I wrote a custom ViewPager to disable Swipe Scroll, but I want to swipe programmatically. I have three Tab in my view pager, but when I call viewPager.setCurrentItem(viewPager.getCurrentItem()+1) on the first Fragment, it moves to the third Fragment instead of the second Fragment. And if I call same function in the second Fragment, it goes to the third. If I call (viewPager.getCurrentItem()-1)` in the third fragment, it works fine by moving back. Any help would be appreciated. My code is below:

NonSwipeAbleViewPager

public class NonSwipeableViewPager extends ViewPager {

private boolean swipeable;

public NonSwipeableViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyViewPager);
    try {
        swipeable = a.getBoolean(R.styleable.MyViewPager_swipeable, true);
    } finally {
        a.recycle();
    }
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    return swipeable ? super.onInterceptTouchEvent(event) : false;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    return swipeable ? super.onTouchEvent(event) : false;
}
}

Declaration in XML

<co.example.customview.NonSwipeableViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    app:swipeable="false" />

Calling it

 @Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.menuNext:
            NonSwipeableViewPager pages = (NonSwipeableViewPager) getActivity().findViewById(R.id.pager);
            pages.setCurrentItem(pages.getCurrentItem()+1, true);
            break;
        default:
            return super.onOptionsItemSelected(item);
    }
    return super.onOptionsItemSelected(item);
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
Tonespy
  • 3,257
  • 7
  • 26
  • 52
  • are you sure that when you press on the menuNext button the first button you are on the fragment at index 0 ? – Blackbelt Mar 10 '15 at 16:08
  • I think I remember some similar oddities when working with it like this at some point. I just can't recall what the resolution was. – Jay Snayder Mar 10 '15 at 16:09
  • Have you tried separating the statements? int currentItem = pages.getCurrentItem(); currentItem++; pages.setCurrentItem(currentItem); – John P. Mar 10 '15 at 16:14
  • I am. I tried to have it Logged by `Log.e("PAGES:", String.valueOf(pager.getCurrentItem()));` The funny thing is that, if I am on the second tab and move to the third tab, it doesnt log. But, if I'm on the first and click on the third Tab, it logs the page as `2` – Tonespy Mar 10 '15 at 16:15
  • @JohnP. Same thing. Moves to the third page – Tonespy Mar 10 '15 at 16:20
  • If you don't want the `ViewPager` to be swipe-able, so why don't you consider using `ViewSwitcher` or `ViewFlipper`? – frogatto Mar 10 '15 at 16:47
  • Well, I was able to debug deeper now. And I noticed something, calling the same `R.id.menuNext` in different fragment makes it move it to the third by default. Fixed it – Tonespy Mar 10 '15 at 16:57
  • @abforce can you attach `ViewFlipper` or `ViewSwitcher` to a Tab? – Tonespy Mar 10 '15 at 17:01
  • @ItuokeAjanlekoko What do you mean by *Tab*? `ViewFlipper` and `ViewSwitcher` is used to switch between a couple of views attached to it. – frogatto Mar 10 '15 at 17:14
  • @abforce same as ViewPager and you can attach it to a Tab indicating to the user which page they're in – Tonespy Mar 10 '15 at 20:41

3 Answers3

90
viewPager.setCurrentItem(idx);

where idx is 0 based integer.

Alp Altunel
  • 3,324
  • 1
  • 26
  • 27
  • 2
    The Question is *ViewPager set current page programatically* , thus this should be the accepted answer! – Yahya Mar 30 '18 at 20:15
35

try this :

  viewPager.postDelayed(new Runnable() {

    @Override
    public void run() {
        viewPager.setCurrentItem(position);
    }
}, 10);

sometimes, setCurrentItem on viewpager doesn't work. As pager's content was controlled by a spinner. both the spinners and the pagers state were restored onResume, and because of this the spinners onItemSelected listener was called during the next event propagation cycle.

By using handler we can make this work because it set the pagers current position after the onItemSelected event fired.

Ajay Chauhan
  • 1,471
  • 4
  • 17
  • 37
33

In your PagerActivity use

    viewPager = (ViewPager) findViewById(R.id.view_pager);
    viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageSelected(int position) {
            int pagei = position + 1;
            pages=pagei + "";

            Toast.makeText(PagerActivity.this, getString(R.string.changeinfopage) + " " + pages, Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }

        @Override
        public void onPageScrollStateChanged(int state) {
        }
    });

and

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {


        switch (item.getItemId()) {

            case R.id.action_previous:

                viewPager.setCurrentItem(viewPager.getCurrentItem() - 1);
                return true;

            case R.id.action_next:

                viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
                return true;
        }

        return super.onOptionsItemSelected(item);

   }
eurosecom
  • 2,932
  • 4
  • 24
  • 38