【发布时间】:2011-11-24 14:38:34
【问题描述】:
我知道通过 Gallery 小部件可以使用 getSelectedItemPosition();检索当前位置,但 ViewPager 似乎没有。
我知道我可以设置一个监听器并在页面切换时检索位置。但我想要当前的视图位置。
【问题讨论】:
我知道通过 Gallery 小部件可以使用 getSelectedItemPosition();检索当前位置,但 ViewPager 似乎没有。
我知道我可以设置一个监听器并在页面切换时检索位置。但我想要当前的视图位置。
【问题讨论】:
你可以使用:
mViewPager.getCurrentItem()
【讨论】:
创建一个监听器并将其设置在您的 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;
}
}
【讨论】:
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)
}
})
【讨论】:
我现在告诉你这是一个 hack,所以没有理由因为这个原因而投反对票。意思是,它要么对你有帮助,要么对你没有帮助。无论哪种方式,下面的描述都将提供一些见解并对社区有所帮助。此外,此解决方案适用于没有 ViewPager.getCurrentItem() 的旧 API。
首先,一些信息。如果您使用 ViewPager.getChildAt(x); 遍历 ViewPager 的所有子项,并使用 toString()(或 getLeft())打印出每个子项 View(一个页面),然后每次更改页面时都执行此操作,您会注意到子项不会当您开始返回页面(返回到开头)时,按照它们显示的逻辑顺序。显然,它将从数组中删除不需要的子元素,然后将最新的子元素附加到数组中。因此,例如,假设您正在查看第 2 页然后更改为第 3 页,您的孩子列表将按此顺序排列page 2, page 3, page 4,这意味着ViewPager.getChildAt(1); 将返回当前页面。但是,如果您随后更改回第 2 页(从第 3 页开始),您的孩子列表将按此顺序排列 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;
}
这个函数可能是一个有问题的 hack,因为它依赖于 getLeft() 的值来解决所有问题。但是,我抓住每个孩子的左坐标。然后我将它与其他值进行比较并存储第一页和第二页,从函数中返回第二页(当前页)。它似乎工作得很好。
为什么(你可能会问)我不只是使用onClickListenter 或其他解决方案?好吧,我确定有一种直接的方法可以做到这一点,而不必包括听众、其他类、不确定的焦点和其他膨胀。不幸的是,这个解决方案并不完全直截了当。但是,它确实消除了臃肿、其他类和侦听器。如果我能找到更直接的方法,我将重写这个函数。或者,这可能会为其他人提供顿悟。
【讨论】:
只有将 TabLayout 链接到 ViewPager 时,我的解决方案才有效。
这就是它们的链接方式:
tabLayout.setupWithViewPager(viewPager);
然后要获取当前位置,您可以使用:
tabLayout.getSelectedTabPosition()
【讨论】: