Call activity after viewpager is finished
Solution 1
private OnPageChangeListener mListener = new OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
// TODO Auto-generated method stub
selectedIndex = arg0;
}
boolean callHappened;
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
if( mPageEnd && arg0 == selectedIndex && !callHappened)
{
Log.d(getClass().getName(), "Okay");
mPageEnd = false;//To avoid multiple calls.
callHappened = true;
}else
{
mPageEnd = false;
}
}
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
if(selectedIndex == adapter.getCount() - 1)
{
mPageEnd = true;
}
}
};
ViewPager.setOnPageChangeListener(mListener);
onPageScrolled
or onPageSelected
any of these you can use here and also check the selected page is equals to the number of items in the ViewPager
.
Solution 2
these three callbacks work like this:
- onPageScrollStateChanged is called with state ViewPager.SCROLL_STATE_DRAGGING
- onPageScrolled will be called many times, its parameter positionOffset and positionOffsetPixels are keep increasing
- onPageScrolled's parameter positionOffset more than 0.5, onPageScrollStateChanged is called with state SCROLL_STATE_SETTLING
- onPageSelected is called with next page index as position
- onPageScrolled will be called many times, its parameter positionOffset and positionOffsetPixels are keep increasing
- onPageScrolled's parameter positionOffset is 1, onPageScrollStateChanged is called with state SCROLL_STATE_IDLE
The logic should not put in onPageSelected and onPageScrollStateChanged, because with them you only know state is changed. only in onPageScrolled you can get the direction. So my implementation is like this:
private int selectedPageIndex = -1;
private boolean exitWhenScrollNextPage = false;
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (exitWhenScrollNextPage && position == PAGE_COUNT - 1) {
exitWhenScrollNextPage = false; // avoid call more times
AndroidLog.error("-------- YEAH!");
}
}
@Override
public void onPageSelected(int position) {
selectedPageIndex = position;
}
@Override
public void onPageScrollStateChanged(int state) {
if (state == SCROLL_STATE_IDLE) {
exitWhenScrollNextPage = selectedPageIndex == PAGE_COUNT - 1;
}
}
Solution 3
Thanks Triode for great answer.
I used the code you posted for my project. In my case, I am finishing the activity if a user swipes to the right on last fragment. It worked fine, but it was still finishing the activity when you swipe to left instead of swiping right.
I made a change in your code and put adapter.getCount() - 1
in place of selectedIndex
. In this case it will not finish the activity if user swipes to left.
if( mPageEnd && arg0 == adapter.getCount()-1 && !callHappened){
Log.d(getClass().getName(), "Okay");
mPageEnd = false;//To avoid multiple calls.
callHappened = true;
}else{
mPageEnd = false;
}
Solution 4
Suggested answers are complex than I thought.So I created a simple one.
I used OnPageChangeListener in ViewPager class. Here we have 3 methods. void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) void onPageSelected(int position); void onPageScrollStateChanged(int state);
It is important to know what are the states in onPageScrollStateChanged() and their sequence of execution.There are 3 states as SCROLL_STATE_IDLE, SCROLL_STATE_DRAGGING and SCROLL_STATE_SETTLING.
Here is the execution order. Scroll_state_dragging --> Scroll_state_settling --> onPageSelected() --> Scroll_state_idle
The idea is keeping a flag inside onPageSelected() to record current page number. Then if user in the last page and swipe left scroll_state_dragging called and launch the next view.
private int pagePosition; // keep a class variable
private int[] layouts= new int[]{
R.layout.welcome_slide1,
R.layout.welcome_slide2,
R.layout.welcome_slide3};
ViewPager.OnPageChangeListener viewPagerPageChangeListener = new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
addBottomDots(position);
pagePosition = position;
}
@Override
public void onPageScrolled(int position, float positionOffset, int arg2) {
}
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_DRAGGING) {
if (pagePosition == layouts.length - 1) {
launchHomeScreen();
}
}
}
};
private void launchHomeScreen() {
startActivity(new Intent(IntroductionActivity.this, MainDockerActivity.class));
finish();
}
I have created a complete example here.
![Anupam](https://i.stack.imgur.com/onuo6.jpg?s=256&g=1)
Comments
-
Anupam almost 2 years
I'm developing an application in which I have to use viewpager and after all items in viewpager is finished I have to call an activity. I'm not able to get event listener for this. Here is what I have been refering too: https://github.com/chiuki/android-swipe-image-viewer/blob/master/src/com/sqisland/android/swipe_image_viewer/MainActivity.java
Here is what I have done so far:
public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager); ImagePagerAdapter adapter = new ImagePagerAdapter(); viewPager.setAdapter(adapter); OnPageChangeListener mListener = new OnPageChangeListener() { @Override public void onPageSelected(int arg0) { // TODO Auto-generated method stub } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { Log.i("Doing something here", "On Scroll state changed"); } }; viewPager.setOnPageChangeListener(mListener); } private class ImagePagerAdapter extends PagerAdapter { private int[] mImages = new int[] { R.drawable.libin1, R.drawable.libin2 }; @Override public int getCount() { return mImages.length; } @Override public boolean isViewFromObject(View view, Object object) { return view == ((ImageView) object); } @Override public Object instantiateItem(ViewGroup container, int position) { Context context = MainActivity.this; ImageView imageView = new ImageView(context); int padding = context.getResources().getDimensionPixelSize( R.dimen.padding_medium); imageView.setPadding(padding, padding, padding, padding); imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); imageView.setImageResource(mImages[position]); ((ViewPager) container).addView(imageView, 0); return imageView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { ((ViewPager) container).removeView((ImageView) object); } } }
My question is how to get event listener if all the items in viewpager is finished.
-
Anupam about 11 yearsAdded this in my code. Printing logs on
onPageScrollStateChanged
, it is printing on every scroll user makes. How to count my array. So, that after array index reaches its end then only fire event. I have edited my question with the updated code. Please see and suggest what should I do? -
Triode about 11 yearsonPageScrolled inside this function just check if the selected index of the ViewPager is same as your array size or not, then fire thr event
-
Anupam about 11 years+1 for your answer. One more thing, whenever I'm sliding it to the second view, my intent is called. Can I call intent when user swipe again on the screen? Right now intent is called as soon as my array index reaches the end.
-
Anupam about 11 yearsHey, I have edited the code what you have written above, and I fall into bug. Whenever I swipe through second page to one,
Log.d(getClass().getName(), "Okay");
is printed. I need just one time print. Can you please also look into my next question over this. Here is the link. stackoverflow.com/questions/16123399/… -
Triode about 11 yearsYou can set a boolean value to denote that the function is already called. And check the boolean value before executing the call
-
Anupam about 11 yearsHow can I do that, can you answer on the next question so that if it works, I can accept your answer.
-
Praneeth over 8 yearsHow do you get the Page_count
-
sotrh over 7 years
PAGE_COUNT
is likely a constant defined at the top of the class. You could use the number of items instead. -
karvoynistas over 7 years@praneethkumar from adapter of view pager like adapter.getCount();