Call activity after viewpager is finished
Asked Answered
R

6

8

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.

Resile answered 11/4, 2013 at 5:3 Comment(3)
Finished !!! can you explain ?Robinette
I think I have explained all in the question. There is nothing to explain. What is your doubt? I have clearly asked the doubt that how can I get event listener or is there any other way to call an activity if user as scrolled to the last item in the viewpager.Resile
"if user as scrolled to the last item in the viewpager." This make more sense brotherRobinette
R
19
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.

Robinette answered 11/4, 2013 at 5:20 Comment(6)
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?Resile
onPageScrolled inside this function just check if the selected index of the ViewPager is same as your array size or not, then fire thr eventRobinette
+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.Resile
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. #16123899Resile
You can set a boolean value to denote that the function is already called. And check the boolean value before executing the callRobinette
How can I do that, can you answer on the next question so that if it works, I can accept your answer.Resile
Z
3

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;
            }

        }
Zanezaneski answered 31/10, 2015 at 18:36 Comment(3)
How do you get the Page_countCretic
PAGE_COUNT is likely a constant defined at the top of the class. You could use the number of items instead.Infelicity
@praneethkumar from adapter of view pager like adapter.getCount();Slalom
O
1

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;
}
Overexcite answered 26/6, 2015 at 19:24 Comment(0)
P
1

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.

Presuppose answered 12/12, 2017 at 4:14 Comment(0)
B
0
@Override
public void onPageScrolled(int pageScrolledOn, float positionOffset, int positionOffsetPixels) {

            if(positionOffset == 0F){
                // meaning you cannot scroll further in current scroll direction

                int lastPage = viewPagerAdapter.getCount - 1;
                if (pageScrolledOn == lastPage){

                    //scroll on last page has occured
                    scrolledOnLastPage = true;
                }
            }

        }
Baranowski answered 5/10, 2015 at 19:5 Comment(0)
G
0

When you are at the last page and you slide to finish the activity the state SCROLL_STATE_SETTLING is skipped and the pager goes directly to SCROLL_STATE_IDLE

private val viewPagerPageChangeListener = object  : ViewPager.OnPageChangeListener{

    var blnPageTriesToSettle = false

    override fun onPageScrollStateChanged(state: Int) {
        when(state){
            SCROLL_STATE_IDLE ->{
                if (!blnPageTriesToSettle){

                    println("You are at the last page and you slide to finish")
                    finish()

                }
            }
            SCROLL_STATE_DRAGGING ->{  blnPageTriesToSettle = false }
            SCROLL_STATE_SETTLING ->{  blnPageTriesToSettle = true }
        }
    }

    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
    }

    override fun onPageSelected(position: Int) {
    }
}
Gutbucket answered 2/11, 2018 at 13:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.