Android ViewPager在滑动到最后一页时的操作

17

我正在努力弄清楚如何在视图页面的最后一页捕获滑动事件。

基本上要求是当用户在最后一页时,试图向下滑动以进入下一页时,活动应关闭。

我已经尝试在onPageScrolled中实现此操作,但似乎无法区分左右滑动。当用户在最后一页时,仍应保留向前移动到上一页的功能。

因此,基本上情况是这样的

When on last page
    if swipe prev (do normal behaviour)
    if swipe next (finish activity)

有人能提供一些建议吗? 谢谢

9个回答

19

这里是可行的解决方案!!

所需变量

....
private boolean isLastPageSwiped;
private int counterPageScroll;
....

ViewPageronPageScrolled

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    //Here 6 is last position 
    if (position == 6 && positionOffset == 0 && !isLastPageSwiped){
        if(counterPageScroll != 0){
            isLastPageSwiped=true;
            //Next Activity here
        }
        counterPageScroll++;
    }else{
        counterPageScroll=0;
    }
}

完美的解决方案。 - Sreehari

13

当用户滑动到你实际上的最后一页时,你应该在你的 ViewPager 中加入一个假的空白页。 当这个假的页面可见时,结束该 Activity

如果此方法无效,您可以尝试示例代码。


1
不是我想要的解决方案,但因为没有其他人提供任何东西,我会给你打勾。 - SikhWarrior
如果您进一步解释,我可以编辑答案。为什么您不喜欢它?它很简单而且有效。 - tasomaniac
6
如果您正在使用任何类型的分页指示器,它会显示为额外的项目。此外,如果您在视图翻页器中覆盖 onDraw 来显示视差图像,则会影响图像滚动的百分比。 - Paul Ruiz
你可以给指示器一个-1的假计数,并自行处理onPageChange以更改指示器。我确定在第一页的onDraw函数中可以忽略它。 - tasomaniac
你使用了什么样的指示器?如果你使用的是库,它们的源代码并不是很大。你可以复制源代码并根据自己的需求进行修改。 它们通常会自动从ViewPager获取页面数,你应该欺骗它们,让它们显示少1页。 - tasomaniac
显示剩余2条评论

9

我可能来晚了,但这可能会帮助其他人。我从stackoverflow的一个问题中得到了代码片段,在那里我只是稍微调整了一下代码。

答案来自这里

ViewPager.OnPageChangeListener pagerListener = new ViewPager.OnPageChangeListener() {
    boolean lastPageChange = false;

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels){
        int lastIdx = mPgScreenAdapter.getCount() - 1;

        Log.d(TAG, "pos:" + position);
        if(lastPageChange && position == lastIdx) {}

    }
    @Override
    public void onPageSelected( int i) {
        pgText.setCurrentItem(i/2);
    }
    @Override
    public void onPageScrollStateChanged(int state) {
        int lastIdx = mPgScreenAdapter.getCount() - 1;

        int curItem = pgScreen.getCurrentItem();
        if(curItem==lastIdx  && state==1){
            lastPageChange = true;

            // i put this here since onPageScroll gets called a couple of times.
            finish();
        }else  { 
            lastPageChange = false;
        }
    }
};

1
这是正确的,但当我将最后一个索引返回到之前时,它也会进入下一个活动。 - Mani

5
int lastPosition;
int currentPosition;


//View pager assign 
ViewPager viewPager = findViewById(R.id.viewPager);
//PageIndicatorView external https://github.com/romandanylyk
PageIndicatorView pageIndicatorView = findViewById(R.id.pageIndicatorView);


//customise pageIndicatorView design
pageIndicatorView.setAnimationType(AnimationType.THIN_WORM);
pageIndicatorView.setViewPager(viewPager);


//BannerAdapter is an custom adapter for viewpage i made.
//assign data here
BannerAdapter pagerAdapter = new BannerAdapter(this, banner, new OnClickListener() {
            @Override
            public void onClick() {

            }
        });
viewPager.setAdapter(pagerAdapter);

//listener for View Pager
//this is where process of making the infinite loop
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            //assign position so that can be manipulated
            currentPosition = position;
        }
        @Override
        public void onPageSelected(int position) {
            //set pager indicator position here 
            pageIndicatorView.setSelection(position);
        }
        @Override
        public void onPageScrollStateChanged(int state) {
            //check state 0 mean no ongoing process
            if(state == 0){
                //check currentPosition == lastPosition to detect that scroll cant scroll anymore
                if(currentPosition == lastPosition){
                    int lastitem = banner.size() - 1;
                    //check position if either last item/first item
                    //and set viewpager current page as follow
                    if(currentPosition == lastitem){
                        viewPager.setCurrentItem(0);
                    }else if(currentPosition == 0){
                        viewPager.setCurrentItem(lastitem);
                    }
                }else{
                    lastPosition = currentPosition;
                }
                Log.d("ScrollState", "currentPosition: " + currentPosition);
            }
            /*empty*/
        }
    });

2

我也试着寻找解决方法。这里有一个可以工作的代码,希望能帮到其他人:

pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {


            }

            @Override
            public void onPageScrollStateChanged(int state) {

                if (state == ViewPager.SCROLL_STATE_IDLE) {
                    int curr = pager.getCurrentItem();
                    int lastReal = pager.getAdapter().getCount() - 1;

                    if (curr < lastReal) {
                        counter = 0;
                    } else if (curr == lastReal) {
                        counter++;

                        if (counter == 2) {

                            pager.setOffscreenPageLimit(0);
                            pager.setCurrentItem(0, false);
                            counter = 0;
                        }


                    }
                }

            }
        });

        pagerIndicator.setViewPager(pager);

我使用计数器作为全局变量。

谢谢!


1

我根据这里的解决方案创建了一个抽象的监听器。当在最后一页向右滑动或在第一页向左滑动时,我想做一些事情。

import android.support.v4.view.ViewPager;

abstract class PageChangeToUnavailablePageListener implements ViewPager.OnPageChangeListener {
    private int finalPageIndex;
    private boolean finalPageVisible = false;
    private boolean firstPageVisible = true;
    private int lastScrollState = 0;

    abstract void onUnavailablePageChangeOnLastPage();
    abstract void onUnavailablePageChangeOnFirstPage();

    public PageChangeToUnavailablePageListener(int finalPageIndex) {
        this.finalPageIndex = finalPageIndex;
    }

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

    @Override
    public void onPageSelected(int i) {
        firstPageVisible = (i == 0);
        finalPageVisible = (i == finalPageIndex);
    }

    @Override
    public void onPageScrollStateChanged(int state) {
        // The normal state sequence for changing pages is
        // DRAGGING (user starts drag), SETTLING (next page is chosen), IDLE (animation is complete).
        // No next page is chosen when dragging right on last page, or left on first page.
        // In this case the SETTLING state is missing and the sequence is (DRAGGING, IDLE).
        if (lastScrollState == ViewPager.SCROLL_STATE_DRAGGING && state == ViewPager.SCROLL_STATE_IDLE) {
            // The user scrolled to an unavailable page.
            if (finalPageVisible) {
                onUnavailablePageChangeOnLastPage();
            } else if (firstPageVisible) {
                onUnavailablePageChangeOnFirstPage();
            }
        }
        lastScrollState = state;
    }
}

那么,如何将这个应用到我的ViewPager中呢? - Noor Hossain

0
希望你已经得到了答案,我也遇到了同样的问题,这是我所做的: 如果你正在使用一个viewpager和一个继承FragmentStatePagerAdapter类的activity,你可以使用getItem(int position)方法来检查是否到达了最后一页。这也适用于你声明了NUM_PAGES,你可以使用它来检测用户是否到达了最后一页。

0

在Activity中:

private static int MAX_LAYOUTS = 3;
private boolean isLastPageSwiped;
private int counterPageScroll;

在onCreate方法中:

ViewPager.OnPageChangeListener viewPagerPageChangeListener = new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
            }

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                if (position == MAX_LAYOUTS - 1 && positionOffset == 0 && !isLastPageSwiped) {
                    if (counterPageScroll != 0) {
                        isLastPageSwiped = true;

                        Intent intent = new Intent(OldActivity.this, NewActivity.class);
                        startActivity(intent);
                    }
                    counterPageScroll++;
                } else {
                    counterPageScroll = 0;
                }
            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
            }
        };
        viewPager.addOnPageChangeListener(viewPagerPageChangeListener);

0

我也有这个问题的解决方案(使用Kotlin)。

例如,我的TabView有3个页面。

......

private var isLastPageSwiped = false
private var indexPageScroll = 0

......

    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
        super.onPageScrolled(position, positionOffset, positionOffsetPixels)
        if (position == 2 && positionOffset == 0f && !isLastPageSwiped) {
            if (indexPageScroll != 0) {
                isLastPageSwiped = true
                //Next Activity here
                //You can perform your action on last page scroll.
            }
            indexPageScroll++
        } else {
            indexPageScroll = 0
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接