onPageSelected не запускается при вызове setCurrentItem(0)
у меня есть деятельность с ViewPager, который отображает кучу фотографий. Когда он запускается, позиция ViewPager устанавливается на основе того, что пользователь выбрал в предыдущем действии. Похоже на галерею.
Я хочу, чтобы onPageSelected вызывался каждый раз при выборе новой страницы, т. е. при первом открытии действия или при переходе пользователя на новую страницу.
Я установил начальную точку следующим образом:
mPager.setCurrentItem(index);
все работает, кроме тех случаев, когда setCurrentItem вызывается с индексом, установленным в 0, так как это не вызовет onPageSelected.
mPager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int index) {
Log.d(TAG, "onPageSelected " + index);
}
...
}
Итак, мой вопрос: это ошибка, и если да, то что я могу с этим поделать?
10 ответов:
самое чистое решение, которое я нашел для этого до сих пор, - это ссылка на onPageChangeListener, которую вы установили на ViewPager (так как я не думаю, что есть ViewPager.getOnPageChangeListener () метод), а затем после установки адаптера ViewPager, вызовите:
onPageChangeListener.onPageSelected(viewPager.getCurrentItem());
однако фрагмент для страницы с текущим индексом еще не был создан (по крайней мере, если вы используете FragmentStatePagerAdapter), поэтому вам может потребоваться обернуть его в runnable, Ала:
viewPager.post(new Runnable(){ @Override public void run() { onPageChangeListener.onPageSelected(viewPager.getCurrentItem()); } });
кроме того, если в обработчике onPageSelected вам нужна ссылка на фрагмент, вам придется сделать это самостоятельно. Я использую абстрактный базовый класс для моего FragmentStatePagerAdapter, который переопределяет методы instantiate и destroy и добавляет/удаляет фрагменты из SparseArray.
хорошо, поэтому я не смог выяснить, является ли это ошибкой (или функцией). Но я подумал, что поделюсь тем, как может выглядеть возможное решение проблемы..
напишите функциональность, которую вы хотите выполнить в методе в действии, а затем вызовите ее в методе onPageSelected.
mPager.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int index) { myOnPageSelectedLogic(index); } ... }
а потом сразу после звонка
setCurrentItem(index);
в упражнении добавьте следующий оператор if
if(index == 0) { myOnPageSelectedLogic(0); }
это не очень красиво, но я надеюсь, что это кому-то помогает:)
на самом деле я думаю, что это ошибка. Я проверил исходный код ViewPager и нашел единственный триггер onPageSelected:
if (dispatchSelected && mOnPageChangeListener != null) { mOnPageChangeListener.onPageSelected(item); }
выше, переменная dispatchSelected определяется код:
final boolean dispatchSelected = mCurItem != item; //item is what you passed to setCurrentItem(item)
и переменная mCurItem определяется и инициализируется как:
private int mCurItem; // Index of currently displayed page.
так mCurItem по умолчанию 0. При вызове setCurrentItem (0), dispatchSelected будет false и, таким образом onPageSelected () не будет отправлен.
теперь мы должны понять, почему вызов setCurrentItem(0) является проблемой, а setCurrentItem (1, или 2, 3...) нет.
Как решить эту проблему:
скопируйте код ViewPager в свой собственный проект и исправьте его:
from final boolean dispatchSelected = mCurItem != item; //the old line to final boolean dispatchSelected = mCurItem != item || mFirstLayout; //the new line
затем используйте свой собственный ViewPager.
так как вы сознательно назвали setCurrentItem (0) и имеете отношение к OnPageChangedListener, отправить onPageSelected () самостоятельно.
听楼下怎么说...
onPageSelected
Не запускается для страницы, которая открывается первой. Для этого случая я вручную выполняю все необходимые действия. Кроме того, я полагаю, что вызовonPageSelected(0)
тоже должен работать.
следующее решение, кажется, работает для меня. т. е. я получаю обратный вызов в позиции 0 при первой загрузке viewpager и для всех последующих выборов либо из прокрутки пользователя, либо из вызова setCurrentItem(x). Я не наблюдал никакого нежелательного поведения.
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { if (positionOffsetPixels == 0) { //Do something on selected page at position } } @Override public void onPageSelected(int position) {} @Override public void onPageScrollStateChanged(int state) {} });
Вы можете продлить
ViewPager
и вызвать слушателя самостоятельно, когда позиция изменяется от 0 до 0public 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. }
самым простым решением будет использование функции, например,
viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrollStateChanged(int state) {} @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {} @Override public void onPageSelected(int position) { onPage(position); } }); // call first time onPage(0); private void onPage(int position) { //... }