Call activity after viewpager is finished

11,286

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.

Share:
11,286
Anupam
Author by

Anupam

Android Developer

Updated on July 28, 2022

Comments

  • Anupam
    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
    Anupam about 11 years
    Added 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
    Triode about 11 years
    onPageScrolled 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
    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
    Anupam about 11 years
    Hey, 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
    Triode about 11 years
    You can set a boolean value to denote that the function is already called. And check the boolean value before executing the call
  • Anupam
    Anupam about 11 years
    How can I do that, can you answer on the next question so that if it works, I can accept your answer.
  • Praneeth
    Praneeth over 8 years
    How do you get the Page_count
  • sotrh
    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
    karvoynistas over 7 years
    @praneethkumar from adapter of view pager like adapter.getCount();