Android ViewPager Prev/Next Button
Asked Answered
P

10

52

Okay, so I'm developing an Android app that utilises a ViewPager to display pages.

Within each page, I have a set of buttons to use for navigating between pages (in addition to the swiping between pages). These buttons are for "first page", "previous page", "next page" and "last page".

What I can't figure out how to do is engineer a mechanism to enable a page change on a button click.

Anyone have any ideas?

ETA: To better explain the setup, the buttons are declared within each page's layout, and are inflated with the rest of the layout within the PagerAdapter. My problem is that I can't reference the ViewPager from within the PagerAdapter. Or at least, I can't think of a way to do it.

Pronator answered 1/6, 2012 at 15:3 Comment(3)
I have the same problem ( don't know how to reference the ViewPager from within the PagerAdapter) , and the Accepted answer doesn't answer that either ( just uses mViewPager without specifying what it is). So how did you get that to work ?Amsden
Well. That was four years ago and I don't have the code to hand. Don't even work for the company any more.Pronator
But I think I did something like having the mViewPager as a class variable rather than a local one. I based this part of the project on one of the 2.5 example projects, so you can probably find something similar to assist. Since doing this, I upgraded the project to use the 4.0 version of things which was quite different as I recall.Pronator
U
118

Button:

Button yourButton = (Button)findViewById(R.id.button1);
    yourButton.setOnClickListener(new OnClickListener() {
        
     @Override
           public void onClick(View view) {
               mViewPager.setCurrentItem(getItem(+1), true); //getItem(-1) for previous
           }
        });

Function:

private int getItem(int i) {
       return mViewPager.getCurrentItem() + i;
}
Unusual answered 8/11, 2012 at 9:17 Comment(2)
This will throw IndexOutOfBoundsExceptions since there is no check for the current position.Archimandrite
This will give some problems, Instead of 1 and -1 you must give viewPager.getCurrentItem() + 1 and viewPager.getCurrentItem() - 1 to next and previous fragmentWye
F
46
yourButton.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View view) {
      yourViewPager.setCurrentItem(page, smoothScroll);
   }
});
Fable answered 1/6, 2012 at 15:22 Comment(5)
I did look into it, and that was my initial thought. But the buttons are declared within the layouts which are inflated inside the adapter which can't reference the ViewPager object itself...Pronator
Then create a custom adapter and pass the viewPager as a variable? or better yet pass a custom event listener.Diffusion
What is page and smoothScroll ?Geodesy
page is yourViewPager.getCurrentItem+-1, smoothScroll is true.Amble
@DennisJaamann Can you tell me in an answer how to do that or give a link? I'm a noobMillur
E
4

1) Make layout

      <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:background="@color/white"
                android:weightSum="1">



                <android.support.v4.view.ViewPager
                    android:id="@+id/images_pager"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    >
                </android.support.v4.view.ViewPager>

                <ImageView
                    android:id="@+id/img_next"
                    android:layout_width="35dp"
                    android:layout_height="35dp"
                    android:src="@drawable/forward_white"
                    android:background="@color/colorPrimary"
                    android:layout_centerVertical="true"
                    android:layout_alignParentRight="true"
                    android:layout_marginRight="5dp"
                    android:paddingTop="5dp"
                    android:paddingBottom="5dp"
                    />


                <ImageView
                    android:id="@+id/img_previous"
                    android:layout_width="35dp"
                    android:layout_height="35dp"
                    android:src="@drawable/back_white"
                    android:background="@color/colorPrimary"
                    android:layout_centerVertical="true"
                    android:layout_marginLeft="5dp"
                    android:layout_alignParentLeft="true"
                    android:paddingTop="5dp"
                    android:paddingBottom="5dp"/>


            </RelativeLayout>

2) Set custom Adapter

        CustomViewPagerAdapter  custompageradpter;
        ViewPager   mViewPager;
        mViewPager = (ViewPager)shareImagesDialouge.findViewById(R.id.images_pager); 
         custompageradpter = new CustomViewPagerAdapter(this);
         mViewPager.setAdapter(custompageradpter);

    public class CustomViewPagerAdapter  extends PagerAdapter {


        Context mContext;
        LayoutInflater mLayoutInflater;

        int[] mResources = {
                R.drawable.emoji_1,
                R.drawable.emoji_2,
                R.drawable.emoji_3,
                R.drawable.emoji_4,
                R.drawable.emoji_5,
                R.drawable.emoji_6
        };

        public CustomViewPagerAdapter(Context context) {
            mContext = context;
            mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public int getCount() {
            return mResources.length;
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == ((LinearLayout) object);
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            View itemView = mLayoutInflater.inflate(R.layout.pager_item, container, false);

            ImageView imageView = (ImageView) itemView.findViewById(R.id.imageView);
            imageView.setImageResource(mResources[position]);

            container.addView(itemView);

            return itemView;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((LinearLayout) object);
        }

    }

3) For next and previous button

         case R.id.img_previous:
                    mViewPager.setCurrentItem(getItemofviewpager(-1), true);
                    break;

                case R.id.img_next:
                    mViewPager.setCurrentItem(getItemofviewpager(+1), true);
                    break;

4) Make this function

  private int getItemofviewpager(int i) {
        return mViewPager.getCurrentItem() + i;
    }
Exaggerate answered 2/8, 2017 at 6:37 Comment(1)
Code only answers arent encouraged as they dont provide much information for future readers please provide some explanation to what you have writtenCalender
S
4

A failproof upgrade to sweggersen's and Alex Orlov's answer,

// For scrolling to next item
nextPageButton.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View view) {
        viewPager.setCurrentItem(getNextPossibleItemIndex(1), true);
    }
});

// For scrolling to previous item
previousPageButton.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View view) {
        viewPager.setCurrentItem(getNextPossibleItemIndex(-1), true);
    }
});

Add getNextPossibleItemIndex() method in your Activity/Fragment,

private int getNextPossibleItemIndex (int change) {

    int currentIndex = viewPager.getCurrentItem();
    int total = viewPager.getAdapter().getCount();

    if (currIndex + change < 0) {
        return 0;
    }

    return Math.abs((currentIndex + change) % total) ;
}

This way, you will be able to change currentItem without worrying about IndexOutOfBoundsException as suggested by Heinrich's comment. Note that using this method, items will be displayed like a circular list.

1 -> 2 -> 3 -> 1 -> 2 -> 3 -> 1

But going back, it will stop at first item

1 <- 1 <- 2 <- 3
Stiver answered 23/2, 2018 at 10:46 Comment(0)
G
4

Do it like this:

backButton=(Button)findViewById(R.id.back_button);
nextButton=(Button)findViewById(R.id.next_button);
backButton.setVisibility(View.INVISIBLE);//you can use GONE or even disable it. It depends on your layout 


    nextButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View view) {
            viewPager.setCurrentItem(viewPager.getCurrentItem()+1, true);
        }
    });


    backButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View view) {
            viewPager.setCurrentItem(viewPager.getCurrentItem()-1, true);
        }
    });
}

To prevent IndexOutOfBoundsException you should hide and show the two buttons like this :

    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int i, float v, int i1) {

        }
        @Override
        public void onPageSelected(int position) {
            if(position==0) {
                backButton.setVisibility(View.INVISIBLE);
            }else  {
                backButton.setVisibility(View.VISIBLE);
            }
            if(position < viewPager.getAdapter().getCount()-1 ) {
                nextButton.setVisibility(View.VISIBLE);
            }else  {
                nextButton.setVisibility(View.INVISIBLE);
            }
        }
        @Override
        public void onPageScrollStateChanged(int i) {

        }
    });
Grayling answered 19/3, 2019 at 13:30 Comment(1)
viewPager.getAdapter().getCount() not resolve in viewpager2?Outwardly
A
3

I finished this project with this code.

vPager = (ViewPager) findViewById(R.id.viewpager);
    View tempView1 = inflater.inflate(R.layout.ani_dialog1, null);
    firstView = (ImageView) tempView1.findViewById(R.id.ani_dialog_next);
    views.add(tempView1);
    firstView.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            vPager.setCurrentItem(1, true);

        }
    }); 
Amesace answered 5/7, 2012 at 6:45 Comment(2)
Why allways item 1? Good that your keeped "// TODO Auto-generated method stub" in the codeNanaam
This will throw IndexOutOfBoundsExceptions since there is no check for the current position.Archimandrite
D
1

Update code

Button preButton = (Button)findViewById(R.id.pre_button);
        Button nextButton = (Button)findViewById(R.id.next_button);

        preButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                mViewPager.setCurrentItem(mViewPager.getCurrentItem()-1, true); 


            }
        });

        nextButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                mViewPager.setCurrentItem(mViewPager.getCurrentItem()+1, true); 

            }
        });
Deepset answered 1/4, 2017 at 5:19 Comment(0)
A
0

First create an interface

public interface OnPageChangedListener {
void OnPageChanged(int position);      }

Next Implement your activity with OnPageChangedListener interface and do the below stuff

private void setupViewPager(ViewPager viewPager){
    viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
    viewPagerAdapter.addFragment(new Fragment1(this));
    viewPagerAdapter.addFragment(new Fragment2(this));
    viewPagerAdapter.addFragment(new Fragment3(this));
    viewPagerAdapter.addFragment(new Fragment4(this));
    viewPagerAdapter.addFragment(new Fragment5(this));
    viewPagerAdapter.addFragment(new Fragment6(this));
    viewPager.setAdapter(viewPagerAdapter);
}
@Override
public void OnPageChanged(int position) {
    viewPager.setCurrentItem(position);
}

In your fragments create a constructor using

private OnPageChangedListener listener;

public Fragment1(OnPageChangedListener listener1) {
    this.listener = listener1;
}

ViewPagerAdapter

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

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

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

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

public void addFragment(Fragment fragment) {
    mFragmentList.add(fragment);
}}

Hope this helps you

Albers answered 17/5, 2019 at 12:39 Comment(0)
D
0

kotlin version using view-binding:

binding.apply {
        btnNext.setOnClickListener { viewPager.currentItem++ }
        btnPrev.setOnClickListener { viewPager.currentItem-- }
}
Darbee answered 23/12, 2023 at 5:47 Comment(0)
B
-4
public void onClick(View v) {
     int currentItem = mViewPager.getCurrentItem();
     mViewPager.setCurrentItem(currentItem+1); //(currentItem-1)
}

only this code in button click: @Override

getcurrentitem is the actual item in viewpager, the next item is currentItem + 1

Bungalow answered 12/10, 2016 at 20:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.