Android ViewPager setCurrentItem не работает после onResume
Ive получил эту странную проблему, setCurrentItem ViewPager (position, false) работает отлично, затем im переключается на другое действие, а после im возвращается к первому действию, ViewPager всегда заканчивается на первом элементе. Несмотря на то, что ive добавил setCurrentItem в метод onResume, он по-прежнему игнорирует его. Его даже не бросает никакого исключения, когда я пытаюсь установить элемент вне индекса границ. Хотя позже, когда я вызываю этот метод, когда нажимается кнопка «Далее», он работает так ожидаемый. Проверил мой код 10 раз для любых возможных вызовов setCurrentItem (0) или smth, но его просто нет вообще.
13 ответов
Я не могу ответить, почему именно это происходит, но если вы откладываете вызов setCurrentItem на несколько миллисекунд он должен работать. Я предполагаю, что это потому, что во время onResume еще не было прохода рендеринга, и ViewPager нуждается в одном или чем-то подобном.
обновление: время истории
Итак, сегодня у меня была проблема, что viewpager проигнорировал мое действие setCurrentItem, и я искал stackoverflow для решения. я нашел кое-кого с та же проблема и исправление; я реализовал исправление, и оно не сработало. ого! вернемся к stackoverflow, чтобы downvote, что faux-fix-provider, и .
это был я. я реализовал свой собственный неисправный non-fix, который я придумал в первый раз, когда я наткнулся на проблему (и который позже был забыт). теперь мне придется понизить голос за предоставление плохой информации.
причина моего первоначального «исправления» работала не из-за» прохода рендеринга»; проблема заключалась в том, что содержимое пейджера контролировалось спиннером. как блесны, так и состояние пейджеров были восстановлены onResume, и из — за этого прослушиватель spinners onItemSelected был вызван во время следующего цикла распространения событий, который действительно перенаселил viewpager-на этот раз используя другое значение по умолчанию.
удаление и сброс прослушивателя во время восстановления исходного состояния Исправлена проблема.
исправление выше вида работало в первый раз, потому что оно установило ток пейджеров позиция после запущено событие onItemSelected. позже он почему — то перестал работать (возможно, приложение стало слишком медленным-в моей реализации я использовал не 100ms, а 10ms). затем я удалил postDelayed в цикле очистки, потому что он не изменил уже неисправное поведение.
обновление 2: Я не могу понизить свой собственный пост. полагаю, достопочтенный сеппуку-единственный оставшийся вариант.
У меня была аналогичная проблема в OnCreate моей деятельности. Адаптер был настроен с правильным количеством и I применяется setCurrentItem после установки адаптера в ViewPager, однако, вернет индекс за пределы. Я думаю, что ViewPager не загрузил все мои фрагменты в тот момент, когда я установил текущий элемент. Разместив runnable на ViewPager, я смог обойти это. Вот пример с небольшим контекстом.
Я нашел очень простой обходной путь для этого:
и, если это не работает, вы можете поместить его в обработчик, но нет необходимости в временной задержке:
у меня такая же проблема и я редактирую
Я NUM_PAGES быть ошибкой только 1.
У меня была аналогичная ошибка в коде, проблема заключалась в том, что я устанавливал позицию перед изменением данных.
решение было просто установить позицию после этого и уведомить об изменении данных
для меня это работало настройка текущего элемента после установки адаптера
я использовал метод post (), описанный здесь, и, конечно же, он отлично работал в некоторых сценариях, но поскольку мои данные поступают с сервера, это не был святой Грааль.
моя проблема была в том, что я хочу иметь
вызывается в произвольное время, а затем переключает вкладки на моем viewPager. Поэтому сразу после вызова notify у меня есть это
забавный факт: / / noinspection deprecation в конце это потому, что есть орфографическая ошибка в API, которая была исправлена после API 16, так что следует прочитать remove OnGlobalLayoutListener вместо removeGlobal OnLayoutListener
это, кажется, охватывает все дела для меня.
Я сделал это таким образом, чтобы восстановить текущего элемента:
это проблема жизненного цикла, как указано в нескольких плакатах здесь. Тем не менее, я нахожу решения с публикацией Runnable быть непредсказуемым и наверное ошибок. Это похоже на способ игнорировать проблему, отправляя ее в будущее.
Я не говорю, что это лучшее решение, но это, безусловно, работает без использования Runnable . Я держу отдельное целое число внутри Fragment что есть ViewPager . это целое число будет содержать страницу мы хотите установить в качестве текущей страницы, когда onResume называется следующий. значение целого числа может быть установлено в любой точке и, таким образом, может быть установлено перед FragmentTransaction или при возобновлении деятельности. Также обратите внимание, что все члены настроены в onResume() , не onCreateView() .
к тому времени, как я позвоню setCurrentItem() представление будет воссоздано. Поэтому на самом деле я призываю setCurrentItem() для viewpager, а затем система вызывает onCreateView() и, следовательно, создает новый viewpager.
это причина для меня, почему я не вижу никаких изменений. И именно по этой причине a postDelayed() может помочь.
теоретическое решение: отложить setCurrentItem() вызов до тех пор, пока представление не будет воссоздано.
практические решение: Я понятия не имею о стабильном и простом решении. Мы должны иметь возможность проверить, собирается ли класс воссоздать его представление, и если это так, отложите вызов setCurrentItem() до конца onCreateView()
Источник
Android ViewPager setCurrentItem не работает после onResume
У меня возникла эта странная проблема: ViewPager setCurrentItem (position, false) работает отлично, а затем переключается на другую активность, а после возврата к первой активности ViewPager всегда заканчивается первым элементом. Несмотря на то, что ive добавил setCurrentItem в метод onResume, он все равно игнорирует его. Он даже не бросает каких-либо исключений, когда я пытаюсь установить элемент из-за пределов индекса. Хотя позже, когда я вызываю этот метод, когда нажата кнопка «next», она работает, как и ожидалось. Проверял мой код 10 раз за любые возможные вызовы setCurrentItem (0) или smth, но его просто не было вообще.
12 ответов
Я не могу действительно ответить ПОЧЕМУ именно это происходит, но если вы задерживаете вызов setCurrentItem в течение нескольких миллисекунд, он должен работать. Я предполагаю, что, поскольку во время onResume пока еще не прошел рендеринг, а ViewPager нужен один или что-то в этом роде.
ОБНОВЛЕНИЕ: время истории
так что сегодня у меня возникла проблема, что viewpager проигнорировал действие setCurrentItem, и я искал stackoverflow для решения. я нашел кого-то с той же проблемой и исправлением; Я реализовал исправление, и оно не сработало. Вау! назад к stackoverflow, чтобы уменьшить этот faux-fix-provider и.
Это был я. я реализовал свои собственные неисправные исправления, которые я впервые придумал, когда я наткнулся на проблему (и которая была позже забыта). теперь я должен отказаться от себя за предоставление плохих сведений.
причина, по которой мое первоначальное «исправление» работало не из-за «прохода рендеринга»; проблема заключалась в том, что содержимое пейджера контролировалось счетчиком. как прядильщики, так и состояние пейджеров были восстановлены в режиме Resume, и из-за этого в течение следующего цикла распространения событий был вызван прядильщик onItemSelected-прослушиватель, который повторно заменил viewpager — на этот раз с использованием другого значения по умолчанию. удаление и сброс слушателя во время восстановления начального состояния устранили проблему.
исправление выше вида — работало в первый раз, потому что оно установило текущую позицию пейджеров после запуска события onItemSelected. позже, по какой-то причине перестало работать (возможно, приложение стало слишком медленным — в моей реализации я не использовал 100 мс, но 10 мс). Затем я удалил postDelayed в цикле очистки, потому что он не изменил уже ошибочное поведение.
update 2: Я не могу понизить свой собственный пост. я предполагаю, что почетный сеппуку — единственный вариант.
Источник
SetCurrentItem в ViewPager не прокручивается сразу в правильном положении
Я использую PagerAdapter. У меня много элементов, поэтому я не загружаю все элементы за одно и то же время. Я перезаряжаю адаптер, я меняю старые элементы на новые элементы. Например, у меня есть 4 элемента, когда я прихожу к последнему элементу, я перезагружаю элементы, и я вызываю setCurentItem (1), чтобы показать viewpager в позиции один. Я провел много испытаний. Я кладу:
Я попытался изменить onPageScrollStateChanged (int arg0), у меня есть только 3 вида и всегда ubicate посередине.
И я попытался изменить onPageSelected (int arg0)
Используя этот последний пример, я прокручиваю представления сразу, но всегда на последней странице. Кто-нибудь знает, как я могу скользить.
Могу ли я узнать больше о том, что вы пытаетесь выполнить?
Во всяком случае, из того, что я могу понять, вы пытаетесь сделать «бесконечный» ViewPager идущий от последнего к первому и наоборот (пожалуйста, поправьте меня, если я ошибаюсь). И вы хотите, чтобы ваш ViewPager переходил на первую страницу, но прокручивал – а не появлялся из ниоткуда.
Ну, если вы отключите гладкую прокрутку (второй параметр), то она перейдет непосредственно на нужную вам страницу без движения прокрутки (и не будет «изменяться» на другие страницы в пути), и если вы включите гладкую Прокрутите, то он просмотрит все виды, поэтому вы увидите, как это было не следующее, а первое.
То, что я могу вам порекомендовать, заключается в том, что вы можете попытаться добавить «фиктивный» вид в позициях 0 и «последний», а вид в позиции 0 будет таким же, как позиция «последний – 1» и «последний», Вид будет таким же, как и позиция «1». Итак, вы сделаете все нормально, ЗА ИСКЛЮЧЕНИЕМ, что в OnPageChangeListener вы будете проверять, является ли текущая страница позицией «0» или «последней», и если она есть, вы вызовете setCurrentItem («1», «ложь») или setCurrentItem («последний – 1 «, false) в зависимости от того, на какой позиции вы сейчас находитесь. Таким образом вы будете сохранять эффект «смены страницы», выполняя то, что хотите.
Надеюсь, это поможет вам в решении вашей проблемы.
ПРИМЕЧАНИЕ. После того, как вы прибудете в новую позицию, у него может быть небольшое изменение, потому что ему нужно будет загрузить представление для текущего, следующего и последнего просмотров (или если вы в 4.0+, тогда он будет загружать только фактическую позицию).
ОБНОВИТЬ:
Если вы измените содержимое списка / массива, определяющего содержимое ViewPager , вам необходимо позвонить:
ОБНОВЛЕНИЕ 2:
Почему вы не добавляете все свои элементы в ViewPager ? У ViewPager уже есть оптимизация для обработки этих случаев, в моем случае у меня много элементов, и он работает как шарм.
Другое дело, в вашем коде я вижу, что вы переходите на среднюю страницу каждый раз, когда страница «поселяется». Но тогда вы действительно никогда не показываете правый и левый вид, так почему вы их имеете?
Последнее, когда вы меняете свой набор данных, вам нужно вызвать метод notifyDataSetChanged, о котором я упоминал выше, а затем вы вызываете метод setCurrentItem внутри обработчика. Если вы этого не сделаете, ваше приложение не будет работать должным образом.
ОБНОВЛЕНИЕ 3:
Ну, единственное, что я могу порекомендовать, это иметь Список, в котором вы продолжаете добавлять новые объекты, которые вы приносите из базы данных, а затем, пока вы продолжаете вставлять объекты в конец списка, нет проблем. Если вы хотите добавить объекты в середине или в начале, вам нужно вызвать notifyDataSetChanged, но это будет немного медленным, потому что оно снова сгенерирует представления. Мы делаем это так, и это работает отлично, и мы даже загружаем информацию с сервера, данные не являются локальными (и на самом деле мы добавляем информацию до конца и начала списка).
Если у вас есть другие вопросы о том, как достичь этого, не стесняйтесь спрашивать.
ОБНОВЛЕНИЕ 4:
На всякий случай, когда кто-то действительно ищет круговой ViewPager , я добавил доказательство концептуального кода, который вы можете повторно использовать. Он работает без проблем, и я использовал его со сложными видами, и все еще нет отставания.
Он не работает без postDelayed, попробуйте с этим кодом:
Источник
Android ViewPager setCurrentItem not working after onResume
I’ve got this strange issue, ViewPager ‘s setCurrentItem(position, false) works perfectly fine, then im switching to another activity, and after I’m back to the first activity, the ViewPager always ends up on the first item. Even though I’ve added setCurrentItem to onResume method it still ignores it. It’s not even throwing any exception when I’m trying to set item to out of bounds index. Though later on when I call this method, when the button «next» is tapped, it works like expected. Checked my code 10 times for any possible calls to setCurrentItem(0) or something but it’s just not there at all.
18 Answers 18
i can’t really answer WHY exactly this happens, but if you delay the setCurrentItem call for a few milliseconds it should work. My guess is that because during onResume there hasn’t been a rendering pass yet, and the ViewPager needs one or something like that.
UPDATE: story time
so today i had the problem that the viewpager ignored my setCurrentItem action, and i searched stackoverflow for a solution. i found someone with the same problem and a fix; i implemented the fix and it didn’t work. whoa! back to stackoverflow to downvote that faux-fix-provider, and .
it was me. i implemented my own faulty non-fix, which i came up with the first time i stumbled over the problem (and which was later forgotten). i’ll now have to downvote myself for providing bad information.
the reason my initial «fix» worked was not because of of a «rendering pass»; the problem was that the pager’s content was controlled by a spinner. both the spinners and the pagers state were restored onResume, and because of this the spinners onItemSelected listener was called during the next event propagation cycle, which did repopulate the viewpager — this time using a different default value.
removing and resetting the listener during the initial state restoration fixed the issue.
the fix above kind-of worked the first time, because it set the pagers current position after the onItemSelected event fired. later, it ceased to work for some reason (probably the app became too slow — in my implementation i didn’t use 100ms, but 10ms). i then removed the postDelayed in a cleanup cycle, because it didn’t change the already faulty behaviour.
update 2: i can’t downvote my own post. i assume, honorable seppuku is the only option left.
Источник