Как добавить бесконечную/бесконечную прокрутку в ViewPager2?

У меня есть FragmentStateAdapter, который подключен к новому ViewPager2. В предыдущей реализации ViewPager было несколько способов реализовать бесконечную/бесконечную прокрутку. Как это сделать в ViewPager2?

Заранее спасибо.


person Ali Yucel Akgul    schedule 06.11.2019    source источник


Ответы (4)


Я новичок в Android, и я провел целый день, читая все сообщения, которые я мог найти об этой проблеме. У меня также есть FragmentStateAdapter с 3 фрагментами, прикрепленными к viewPager2.

Мое решение состояло в том, чтобы переопределить событие OnPageChangeCallback. Здесь я сохранил в двух локальных переменных состояние и текущее положение; затем в onPageScrolled я добавил элемент управления, чтобы понять:

  1. если началось событие свайпа
  2. если новая позиция была равна текущей позиции. Наблюдая за логами, я заметил, что они одинаковы только при попытке прокрутить с первой страницы влево или с последней вправо.
  3. если позиция страницы была первой или последней

Если бы все эти условия были верны и я был на первой странице, то я бы сделал следующую страницу последней и наоборот.

Вот мой код. Я использовал 0 и 2, потому что у меня есть 3 фрагмента.

viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback()
{
    private int myState;
    private int currentPosition;

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
    {
        if (myState == ViewPager2.SCROLL_STATE_DRAGGING && currentPosition == position && currentPosition == 0)
            viewPager2.setCurrentItem(2);
        else if (myState == ViewPager2.SCROLL_STATE_DRAGGING && currentPosition == position && currentPosition == 2)
            viewPager2.setCurrentItem(0);

        super.onPageScrolled(position, positionOffset, positionOffsetPixels);
    }

    @Override
    public void onPageSelected(int position)
    {
        currentPosition = position;

        super.onPageSelected(position);
    }

    @Override
    public void onPageScrollStateChanged(int state)
    {
        myState = state;

        super.onPageScrollStateChanged(state);
    }
});
person Claudiu Razlet    schedule 08.11.2020
comment
Этот фрагмент кода спасает мои однодневные усилия. Все, хотя я искал что-то еще, но используя эту логику, мы можем ограничить несколько вызовов onPageScrolled. - person Subho; 17.01.2021

Вот что я придумал:

class EndlessScrollAdapter internal constructor(
    fm: FragmentManager,
    lifeCycle: Lifecycle
) : FragmentStateAdapter(fm, lifeCycle) {

    private val items = mutableListOf<YourModel>()
    val firstElementPosition = Int.MAX_VALUE / 2

    fun updateList(list: List<YourModel>) {
        items.apply {
            clear()
            addAll(list)
        }
        notifyDataSetChanged()
    }

    override fun getItemCount(): Int = if (items.isNotEmpty()) Int.MAX_VALUE else 0

    override fun createFragment(position: Int): Fragment = YourPagerFragment(
        items[position.rem(items.size)])
}

В Activity или Fragment нам нужно вызвать:

viewPager2.adapter = endlessScrollAdapter
endlessScrollAdapter.apply {
  updateList(yourModelList)
  viewPager2.setCurrentItem(this.firstElementPosition, false)
}

Буквально это не бесконечно, но с точки зрения пользователя это так, поскольку он никогда не достигнет края. Длина ViewPager2 — Int.MAX_VALUE, начальная позиция — Int.MAX_VALUE/2, поэтому пользователь может прокручивать вперед и назад.

person Da Artagnan    schedule 24.11.2019
comment
Что такое ViewPagerFragment? Я пропустил код? - person user1801179; 21.04.2021
comment
@user1801179 user1801179 это просто твой собственный фрагмент. Это НЕ встроенный класс Android. В приведенном выше случае я использую один и тот же фрагмент — ViewPagerFragment — для всех страниц в ViewPager2. - person Da Artagnan; 21.04.2021

вы должны вернуть первую или последнюю позицию view_pager после завершения прокрутки.

см. эту проблему - Изменение ViewPager для включения бесконечной прокрутки страницы

person HGH806    schedule 06.11.2019
comment
Большое спасибо за ваш комментарий, но ссылка, которую вы дали, предназначена для ViewPager, мне нужен адаптер ViewPager2. (Это в основном адаптер recyclerview) - person Ali Yucel Akgul; 07.11.2019

Определите класс, расширяющий ViewPager2.OnPageChangeCallback:

class ViewPager2PageChangeCallback(private val listener: (Int) -> Unit) :
        ViewPager2.OnPageChangeCallback() {

    override fun onPageSelected(position: Int) {
        super.onPageSelected(position)
        when (position) {
            0 -> listener.invoke(5). // 0th element is a fake element in your list. When 0th element is opened(from 1 to 0) automatically open last element(5th index)
            6 -> listener.invoke(1). // 6th element is a fake element in your list. When 6th element is opened(from 5 to 6) automatically open first element(1th index)
        }
    }
}

Затем создайте экземпляр из него в своей деятельности.

onCreate(){
    viewPager2PageChangeCallback = ViewPager2PageChangeCallback {
        viewPager2.post {
            viewPager2.setCurrentItem(it, false)
        }
    }
    viewPager2.registerOnPageChangeCallback(viewPager2PageChangeCallback)
}

Отмените регистрацию, когда активность будет уничтожена.

override fun onDestroy() {
    super.onDestroy()
    viewPager2.unregisterOnPageChangeCallback(viewPager2PageChangeCallback)
}
person oiyio    schedule 30.01.2020