获取ViewPager的当前位置

87

我知道使用“getSelectedItemPosition()”可以获取到Gallery小部件的当前位置,但似乎ViewPager没有此功能。

我知道可以设置监听器,在页面切换时检索位置。但是我想要当前视图的位置。

5个回答

203

您可以使用:

mViewPager.getCurrentItem()

ViewPager中没有getCurrentItem方法。 - Dmitry Guselnikov
20
有的:http://developer.android.com/reference/android/support/v4/view/ViewPager.html#getCurrentItem() - Terry
3
抱歉,我错了。刚刚更新了我的支持库,这个方法在新版本中存在。 - Dmitry Guselnikov

94

创建一个监听器并将其设置在你的ViewPager上:

/**
 * Get the current view position from the ViewPager by
 * extending SimpleOnPageChangeListener class and adding your method
 */
public class DetailOnPageChangeListener extends ViewPager.SimpleOnPageChangeListener {

    private int currentPage;

    @Override
    public void onPageSelected(int position) {
        currentPage = position;
    }

    public final int getCurrentPage() {
        return currentPage;
    }
}

4
使用该方法时请注意:当视图从未更改时,getCurrentPage()总是会返回0. 如果您在ViewPager上进入某个非第一个视图,由于某种原因,您期望的值不应该是0...我遇到了这个问题,因为我并不总是从第一个视图进入该视图。 - Brandon Romano
1
@Adam,你能告诉我如何调用getCurrentPage函数吗? - user3233280
非常简单。谢谢您的 Android。 - whdals0

7

2019更新

现在您可以在View Pager上设置addOnPageChangeListener来观察页面位置的变化。

由于您想要设置侦听器并在页面切换时检索位置,因此可以这样做。

mViewPager.addOnPageChangeListener(object : OnPageChangeListener {
            override fun onPageScrollStateChanged(state: Int) {}
            override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}

            override fun onPageSelected(position: Int) {
                pagePosition.setText("" + position + "/" + galleryAdapter!!.count)
            }
        })

1
我的解决方案仅在您的ViewPager与TabLayout链接时才有效。
这是它们如何链接的:
tabLayout.setupWithViewPager(viewPager);

然后要获取当前位置,您可以使用以下方法:

tabLayout.getSelectedTabPosition()

0

我现在告诉你这是个hack,所以没有理由为此而投反对票。也就是说,它可能会对你有帮助,也可能不会。无论如何,下面的描述将提供一些见解,并对社区有所帮助。此外,这个解决方案适用于旧的API,没有 ViewPager.getCurrentItem() 方法。


首先,一点信息。如果你用ViewPager.getChildAt(x);循环遍历ViewPager的所有子视图,并且使用toString()(或者getLeft())打印出每个子视图(即页面),然后每次切换页面时都这样做,你会发现子视图的顺序不是它们显示时的逻辑顺序,尤其是当你开始回退页面时(即返回到开头)。显然,它会从数组中删除不需要的子视图,然后将最新的子视图追加到数组末尾。所以,例如,假设你正在查看第2页,然后切换到第3页,你的子视图列表将按照这个顺序排列:page 2, page 3, page 4,意味着ViewPager.getChildAt(1);将返回当前页。但是,如果你再次从第3页切换回第2页,你的子视图列表将按照这个顺序排列:page 2, page 3, page 1,这意味着ViewPager.getChildAt(1);不会返回当前页。我还没有找到简单的逻辑来利用这些信息筛选出当前页。因为getChildAt后面的页面数组的顺序是基于用户翻页行为而定的,所以是任意的。

话虽如此,我开发了一个hack解决方案。我不知道这个函数是否适用于所有环境,但它适用于我的当前项目。如果对您来说不起作用,那么可能是不同API级别的问题。但我实际上并不认为其他环境会有任何问题。

现在,进入正题。我注意到ViewPager.getChildAt(x).getLeft()的结果将具有相对于父级的某种水平像素坐标。因此,我使用这些信息来筛选出当前视图。

private int getCurrentPageIndex(ViewPager vp){
    int first,second,id1,id2,left;
    id1 = first = second = 99999999;
    View v;
    for ( int i = 0, k = vp.getChildCount() ; i < k ; ++i ) {
        left = vp.getChildAt(i).getLeft();
        if ( left < second ) {
            if ( left < first ) {
                second = first;
                id2 = id1;
                first = left;
                id1 = i;
            } else {
                second = left;
                id2 = i;
            }
        }
    }
    return id2;
}

这个函数可能是一个可疑的黑客,因为它依赖于getLeft()的值来解决所有问题。但是,我抓取每个子元素的左坐标。然后将其与其他值进行比较,并存储第一页和第二页,从函数中返回第二页(当前页)。它似乎工作得很好。

你可能会问,为什么我不使用onClickListenter或其他解决方案呢?嗯,我非常确定有一种简单直接的方法可以做到这一点,而不必包含监听器、其他类、不确定的焦点和其他臃肿的东西。不幸的是,这个解决方案并不是非常直接。但是,它确实消除了臃肿、其他类和监听器。如果我能找到更直接的方法,我会重写这个函数。或者,也许这会为其他人提供启示,让他们有所领悟。


1
你真救了我!有个极难搞的 Bug,一直找不到出问题的地方。您,先生,应该得到无数个点赞! - Nursultan Talapbekov
谢谢先生们!我猜社区没有分享你们的热情。 - Pimp Trizkit

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