获取 ViewPager 的当前位置

我知道通过 Gallery 小部件我可以使用 getSelectedItemposition () ; 检索当前位置,但是看起来 ViewPager 没有这个功能。

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

91460 次浏览

Create a listener and set it on your 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;
}
}

I'm telling you now its a hack, so there is no reason to downvote for that reason. Meaning, it either will be helpful to you specifically or not. Either way, the description below will provide some insight and be helpful to the community. Also, this solution is good for the older APIs that don't have ViewPager.getCurrentItem().


First, a little information. If you iterate thru all children of a ViewPager with ViewPager.getChildAt(x); and print out with toString() (or getLeft()) each child View (a page) and then do this everytime you change pages, you will notice that the children will not be in the logical order that they are displayed in when you start going back pages (paging back to the beginning). Apparently, it will remove the unneeded child from the array then append the newest child to the array. So, for example, lets say you are looking at page 2 then changed to page 3, your list of children will be in this order page 2, page 3, page 4 meaning that ViewPager.getChildAt(1); will return the current page. But, if you then change back to page 2 (from page 3) your list of children will be in this order page 2, page 3, page 1 which means that ViewPager.getChildAt(1); does not return the current page. I have not yet been able to find simple logic to weed out the current page using this information. Because the order of the pages in the array behind getChildAt is in an arbitrary order based off of how the user has been paging around.

That being said, I developed a hack work-around. I have no clue if this function will work in all in environments, but it works for my current project. I would suspect if doesn't for you, then its an issue of different API level. But I dont actually suspect any issues for other environments.

Now, onto the meat. What I noticed was that the result of ViewPager.getChildAt(x).getLeft() will have some type of horizontal pixel coordinate relative to the parent. So, I used this information to weed out which view is the current one.

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

This function is probably a questionable hack because it relies on the value of getLeft() to figure it all out. But, I grab the left coordinate of each child. I then compare this to the other values and store the first and second pages, returning the second page (current page) out of the function. It seems to work beautifully.

Why (might you ask) didn't I just use onClickListenter or whatever solution? Well, I was darned determined that there was a straight forward way to do this without having to include listeners, other classes, inconclusive focus, and other bloat. Unfortunately, this solution is not exactly straight forward. But, it does do away with the bloat, other classes and listeners. If I can figure out a more straight forward way, I will be rewriting this function. Or maybe, this will provide insight for someone else to have an epiphany.

You can use:

mViewPager.getCurrentItem()

Update 2019

Now you can set addOnPageChangeListener on View Pager to Observe change in Page position.

Since you wanted to setup a listener and retrieve the position when the page is switched

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

My solution would only work if you have a TabLayout linked to your ViewPager.

This is how they're linked:

tabLayout.setupWithViewPager(viewPager);

And then to get current position, you can make use of:

tabLayout.getSelectedTabPosition()