86

我知道画廊小部件可以使用 getSelectedItemPosition(); 检索当前位置,但 ViewPager 似乎没有。

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

4

5 回答 5

201

您可以使用:

mViewPager.getCurrentItem()
于 2013-04-05T10:15:51.273 回答
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;
    }
}
于 2011-11-24T14:42:40.010 回答
6

2019 年更新

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

由于您想设置一个侦听器并在切换页面时检索位置

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)
            }
        })
于 2019-06-26T14:44:40.727 回答
0

我现在告诉你它是一个黑客,所以没有理由因为这个原因而拒绝投票。意思是,它要么对你有帮助,要么对你没有帮助。无论哪种方式,下面的描述都将提供一些见解并对社区有所帮助。此外,此解决方案适用于没有ViewPager.getCurrentItem().


首先,一点信息。如果您遍历 ViewPager 的所有子项并使用(或)每个子视图(页面)ViewPager.getChildAt(x);打印出来,然后每次更改页面时都执行此操作,您会注意到子项不会按照显示的逻辑顺序排列在您开始返回页面时(页面返回到开头)。显然,它将从数组中删除不需要的子元素,然后将最新的子元素附加到数组中。因此,例如,假设您正在查看第 2 页然后更改为第 3 页,您的孩子列表将按此顺序排列,这意味着将返回当前页面。但是,如果您随后更改回第 2 页(从第 3 页开始),您的孩子列表将按此顺序排列,这意味着toString()getLeft()page 2, page 3, page 4ViewPager.getChildAt(1);page 2, page 3, page 1ViewPager.getChildAt(1);不返回当前页面。我还没有找到简单的逻辑来使用这些信息清除当前页面。因为后面数组中页面的getChildAt顺序是基于用户如何分页的任意顺序。

话虽如此,我开发了一个黑客解决方法。我不知道这个功能是否适用于所有环境,但它适用于我当前的项目。我怀疑如果不适合你,那么它是不同 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;
}

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

为什么(你可能会问)我不只是使用onClickListenter或任何解决方案?好吧,我确定有一种直接的方法可以做到这一点,而不必包括听众、其他类、不确定的焦点和其他膨胀。不幸的是,这个解决方案并不完全直截了当。但是,它确实消除了臃肿、其他类和侦听器。如果我能找到更直接的方法,我将重写这个函数。或者,这将为其他人提供顿悟的洞察力。

于 2013-03-01T21:05:41.693 回答
0

我的解决方案只有在您将 TabLayout 链接到 ViewPager 时才有效。

这是它们的链接方式:

tabLayout.setupWithViewPager(viewPager);

然后要获得当前位置,您可以使用:

tabLayout.getSelectedTabPosition()
于 2021-07-28T19:01:53.277 回答