I have an Activity with a ViewPager which displays a bunch of pictures. When it starts the ViewPager\'s position is set based on what the user selected in a previous Activit
Actually I think this is a BUG. I've check the source code of ViewPager and found the only trigger of onPageSelected:
if (dispatchSelected && mOnPageChangeListener != null) {
mOnPageChangeListener.onPageSelected(item);
}
Above, variable dispatchSelected is determined by code:
final boolean dispatchSelected = mCurItem != item;
//item is what you passed to setCurrentItem(item)
And, variable mCurItem is defined and initialized as:
private int mCurItem; // Index of currently displayed page.
So mCurItem is default to 0. When calling setCurrentItem(0), dispatchSelected will be false thus onPageSelected() will not be dispatched.
Now we should understand why calling setCurrentItem(0) is a problem while setCurrentItem(1, or 2, 3...) is not.
How to solve this problem:
Copy the code of ViewPager to your own project and fix it:
from
final boolean dispatchSelected = mCurItem != item; //the old line
to
final boolean dispatchSelected = mCurItem != item || mFirstLayout; //the new line
then use your own ViewPager.
Since you consciously called setCurrentItem(0) and have a refrence to the OnPageChangedListener, dispatch the onPageSelected() by yourself.
听楼下怎么说...
Ok, so I haven't been able to figure out whether this is a bug (or a feature). But I thought I'd share how a possible solution to the problem could look..
Write the functionality you wish to perform in a method in the Activity and then call this in the onPageSelected method.
mPager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int index) {
myOnPageSelectedLogic(index);
}
...
}
And then right after calling
setCurrentItem(index);
in the Activity, add the following if statement
if(index == 0) {
myOnPageSelectedLogic(0);
}
It's not super pretty but I hope it helps someone :)
You can extend the ViewPager
and call the Listener by yourself when the position is changed from 0 to 0
public class BetterViewPager extends ViewPager {
public BetterViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
// we some the listner
protected OnPageChangeListener listener;
@Override
public void setOnPageChangeListener(OnPageChangeListener listener) {
super.setOnPageChangeListener(listener);
this.listener = listener;
}
@Override
public void setCurrentItem(int item) {
// when you pass set current item to 0,
// the listener won't be called so we call it on our own
boolean invokeMeLater = false;
if(super.getCurrentItem() == 0 && item == 0)
invokeMeLater = true;
super.setCurrentItem(item);
if(invokeMeLater && listener != null)
listener.onPageSelected(0);
}
}
public class PageChangeListener implements 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 && getCurrentItem() == 0) {
//this indicate viewpager finish scroll and page at position 0 is selected.
}