Изменение ViewPager для включения бесконечной прокрутки страниц - PullRequest
41 голосов
/ 14 октября 2011

Джон Уиллис опубликовал информацию о том, как включить бесконечную прокрутку своего кода. Там он сказал, что внес некоторые изменения в класс ViewPager в библиотеке поддержки Android. Какие изменения были внесены и как можно «перекомпилировать» библиотеку с изменением ViewPager?

Ответы [ 10 ]

37 голосов
/ 04 марта 2012

Я решил эту проблему очень просто, используя небольшой взлом адаптера. Вот мой код:

public class MyPagerAdapter extends FragmentStatePagerAdapter
{
    public static int LOOPS_COUNT = 1000;
    private ArrayList<Product> mProducts;


    public MyPagerAdapter(FragmentManager manager, ArrayList<Product> products)
    {
        super(manager);
        mProducts = products;
    }


    @Override
    public Fragment getItem(int position)
    {
        if (mProducts != null && mProducts.size() > 0)
        {
            position = position % mProducts.size(); // use modulo for infinite cycling
            return MyFragment.newInstance(mProducts.get(position));
        }
        else
        {
            return MyFragment.newInstance(null);
        }
    }


    @Override
    public int getCount()
    {
        if (mProducts != null && mProducts.size() > 0)
        {
            return mProducts.size()*LOOPS_COUNT; // simulate infinite by big number of products
        }
        else
        {
            return 1;
        }
    }
} 

А затем в ViewPager мы устанавливаем текущую страницу посередине:

mAdapter = new MyPagerAdapter(getSupportFragmentManager(), mProducts);
mViewPager.setAdapter(mAdapter);
mViewPager.setCurrentItem(mViewPager.getChildCount() * MyPagerAdapter.LOOPS_COUNT / 2, false); // set current item in the adapter to middle
32 голосов
/ 02 декабря 2011

Спасибо за ваш ответ, Шериф.

Я решил это немного по-другому.

Я изменил код класса ViewPager библиотеки поддержки Android.Метод setCurrentItem(int)

изменяет страницу с анимацией.Этот метод вызывает внутренний метод, для которого требуется индекс и флаг, обеспечивающий плавную прокрутку.Этот флаг boolean smoothScroll.Расширение этого метода вторым параметром boolean smoothScroll решило его для меня.Вызов этого метода setCurrentItem(int index, boolean smoothScroll) позволил мне бесконечно прокручивать его.

Вот полный пример:

Обратите внимание, что отображается только центральная страница.Более того, я сохранял страницы по отдельности, что позволяло мне более легко обрабатывать их.

private class Page {
  View page;
  List<..> data;
}
// page for predecessor, current, and successor
Page[] pages = new Page[3];




mDayPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

        @Override
        public void onPageSelected(int position) {
        }

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}

        @Override
        public void onPageScrollStateChanged(int state) {

            if (state == ViewPager.SCROLL_STATE_IDLE) {

                if (mFocusedPage == 0) {
                    // move some stuff from the 
                                            // center to the right here
                    moveStuff(pages[1], pages[2]);

                    // move stuff from the left to the center 
                    moveStuff(pages[0], pages[1]);
                    // retrieve new stuff and insert it to the left page
                    insertStuff(pages[0]);
                }
                else if (mFocusedPage == 2) {


                    // move stuff from the center to the left page
                    moveStuff(pages[1], pages[0]); 
                    // move stuff from the right to the center page
                    moveStuff(pages[2], pages[1]); 
                    // retrieve stuff and insert it to the right page
                                            insertStuff(pages[2]);
                }

                // go back to the center allowing to scroll indefinitely
                mDayPager.setCurrentItem(1, false);
            }
        }
    });

Однако без кода Джона Уиллиса я бы сам не решил его.

РЕДАКТИРОВАТЬ: вот блог 1021 * об этом:

31 голосов
/ 02 июля 2013

Бесконечный просмотр пейджера путем переопределения 4 методов адаптера в существующем классе адаптеров

    @Override
    public int getCount() {
        return Integer.MAX_VALUE;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        String title = mTitleList.get(position % mActualTitleListSize);
        return title;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        int virtualPosition = position % mActualTitleListSize;
        return super.instantiateItem(container, virtualPosition);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        int virtualPosition = position % mActualTitleListSize;
        super.destroyItem(container, virtualPosition, object);
    }
9 голосов
/ 23 ноября 2011

Все, что вам нужно сделать, это посмотреть пример здесь

Вы найдете, что в строке 295 страница всегда установлена ​​на 1, чтобы ее можно было прокручивать и что количество страниц равно 3 в методе getCount().

Это две основные вещи, которые вам нужно изменить, остальное - ваша логика, и вы можете обращаться с ними по-разному.

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

p.s. этот код не мой, на него ссылались в вопросе, который вы указали в своем вопросе

6 голосов
/ 27 декабря 2012

На самом деле, я искал различные способы сделать эту «бесконечную» нумерацию страниц, и хотя человеческое представление о времени таково, что оно бесконечно (хотя у нас есть представление о начале и конце времени), компьютеры разбираются в дискретном.Существует минимальное и максимальное время (которое может быть скорректировано с течением времени, помните основание напуга Y2K?).

В любом случае, смысл этого обсуждения заключается в том, что этого достаточно / должно быть достаточно для поддержки относительно бесконечного диапазона дат через фактически конечный диапазон дат.Прекрасным примером этого является реализация CalendarView платформы Android и WeeksAdapter внутри нее.Минимальная дата по умолчанию - 1900, а максимальная дата по умолчанию - 2100, это должно охватывать 99% календарного использования любого человека в радиусе 10 лет вокруг сегодняшнего дня.

Что они делают в своей реализации (ориентированы на недели), так это вычисляют количество недель между минимальной и максимальной датой.Это становится количеством страниц в пейджере.Помните, что пейджер не должен поддерживать все эти страницы одновременно (setOffscreenPageLimit(int)), он просто должен иметь возможность создавать страницу на основе номера страницы (или индекса / позиции).В этом случае индекс - это количество недель, от которых неделя начинается с минимальной даты.При таком подходе вам просто нужно поддерживать минимальную дату и количество страниц (расстояние до максимальной даты), тогда для любой страницы вы можете легко вычислить неделю, связанную с этой страницей.Не нужно танцевать вокруг того факта, что ViewPager не поддерживает циклическое воспроизведение (или бесконечную нумерацию страниц) и пытается заставить его вести себя так, как будто он может бесконечно прокручиваться.

new FragmentStatePagerAdapter(getFragmentManager()) {
    @Override
    public Fragment getItem(int index) {
        final Bundle arguments = new Bundle(getArguments());
        final Calendar temp_calendar = Calendar.getInstance();
        temp_calendar.setTimeInMillis(_minimum_date.getTimeInMillis());
        temp_calendar.setFirstDayOfWeek(_calendar.getStartOfWeek());
        temp_calendar.add(Calendar.WEEK_OF_YEAR, index);
        // Moves to the first day of this week
        temp_calendar.add(Calendar.DAY_OF_YEAR,
                -UiUtils.modulus(temp_calendar.get(Calendar.DAY_OF_WEEK) - temp_calendar.getFirstDayOfWeek(),
                7));
        arguments.putLong(KEY_DATE, temp_calendar.getTimeInMillis());
        return Fragment.instantiate(getActivity(), WeekDaysFragment.class.getName(), arguments);
    }

    @Override
    public int getCount() {
        return _total_number_of_weeks;
    }
};

Тогда WeekDaysFragment может легко отобразитьнеделю, начинающуюся с даты, указанной в аргументах.

В качестве альтернативы, кажется, что в некоторой версии приложения Календарь на Android используется ViewSwitcher (что означает, что есть только 2 страницы: ту, которую вы видите, и скрытую страницу).Затем он изменяет анимацию перехода в зависимости от того, как пользователь провел пальцем, и соответственно отображает следующую / предыдущую страницу.Таким образом, вы получаете бесконечное разбиение на страницы, потому что оно просто переключается между двумя страницами бесконечно.Это требует использования View для страницы, хотя я и пошел с первым подходом.

В общем, если вы хотите "бесконечную нумерацию страниц", это, вероятно, потому что ваши страницы основаны на датах илираз как-то.Если это так, рассмотрите возможность использования конечного подмножества времени, которое относительно бесконечно.Вот как CalendarView реализован, например.Или вы можете использовать ViewSwitcher подход.Преимущество этих двух подходов состоит в том, что ни один из них не делает ничего особенно необычного с ViewSwitcher или ViewPager, и не требует никаких уловок или переопределений, чтобы заставить их вести себя бесконечно (ViewSwitcher уже предназначен для бесконечного переключения между представлениями)., но ViewPager предназначен для работы на конечном, но не обязательно постоянном наборе страниц).

2 голосов
/ 03 декабря 2015

Его взломали CustomPagerAdapter :

MainActivity.java

import android.content.Context;
import android.os.Handler;
import android.os.Parcelable;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private List<String> numberList = new ArrayList<String>();
    private CustomPagerAdapter mCustomPagerAdapter;
    private ViewPager mViewPager;
    private Handler handler;
    private Runnable runnable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        numberList.clear();
        for (int i = 0; i < 10; i++) {
        numberList.add(""+i);
        }

        mViewPager = (ViewPager)findViewById(R.id.pager);
        mCustomPagerAdapter = new CustomPagerAdapter(MainActivity.this);
        EndlessPagerAdapter mAdapater = new EndlessPagerAdapter(mCustomPagerAdapter);
        mViewPager.setAdapter(mAdapater);


        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                int modulo = position%numberList.size();
                Log.i("Current ViewPager View's Position", ""+modulo);

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        handler = new Handler();
        runnable = new Runnable() {
            @Override
            public void run() {

                mViewPager.setCurrentItem(mViewPager.getCurrentItem()+1);
                handler.postDelayed(runnable, 1000);
            }
        };

        handler.post(runnable);

    }

    @Override
    protected void onDestroy() {
        if(handler!=null){
            handler.removeCallbacks(runnable);
        }
        super.onDestroy();
    }

    private class CustomPagerAdapter extends PagerAdapter {

        Context mContext;
        LayoutInflater mLayoutInflater;

        public CustomPagerAdapter(Context context) {
            mContext = context;
            mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public int getCount() {
            return numberList.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == ((LinearLayout) object);
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            View itemView = mLayoutInflater.inflate(R.layout.row_item_viewpager, container, false);

            TextView textView = (TextView) itemView.findViewById(R.id.txtItem);
            textView.setText(numberList.get(position));
            container.addView(itemView);
            return itemView;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((LinearLayout) object);
        }
    }

    private class EndlessPagerAdapter extends PagerAdapter {

        private static final String TAG = "EndlessPagerAdapter";
        private static final boolean DEBUG = false;

        private final PagerAdapter mPagerAdapter;

        EndlessPagerAdapter(PagerAdapter pagerAdapter) {
            if (pagerAdapter == null) {
                throw new IllegalArgumentException("Did you forget initialize PagerAdapter?");
            }
            if ((pagerAdapter instanceof FragmentPagerAdapter || pagerAdapter instanceof FragmentStatePagerAdapter) && pagerAdapter.getCount() < 3) {
                throw new IllegalArgumentException("When you use FragmentPagerAdapter or FragmentStatePagerAdapter, it only supports >= 3 pages.");
            }
            mPagerAdapter = pagerAdapter;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            if (DEBUG) Log.d(TAG, "Destroy: " + getVirtualPosition(position));
            mPagerAdapter.destroyItem(container, getVirtualPosition(position), object);

            if (mPagerAdapter.getCount() < 4) {
                mPagerAdapter.instantiateItem(container, getVirtualPosition(position));
            }
        }

        @Override
        public void finishUpdate(ViewGroup container) {
            mPagerAdapter.finishUpdate(container);
        }

        @Override
        public int getCount() {
            return Integer.MAX_VALUE; // this is the magic that we can scroll infinitely.
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return mPagerAdapter.getPageTitle(getVirtualPosition(position));
        }

        @Override
        public float getPageWidth(int position) {
            return mPagerAdapter.getPageWidth(getVirtualPosition(position));
        }

        @Override
        public boolean isViewFromObject(View view, Object o) {
            return mPagerAdapter.isViewFromObject(view, o);
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            if (DEBUG) Log.d(TAG, "Instantiate: " + getVirtualPosition(position));
            return mPagerAdapter.instantiateItem(container, getVirtualPosition(position));
        }

        @Override
        public Parcelable saveState() {
            return mPagerAdapter.saveState();
        }

        @Override
        public void restoreState(Parcelable state, ClassLoader loader) {
            mPagerAdapter.restoreState(state, loader);
        }

        @Override
        public void startUpdate(ViewGroup container) {
            mPagerAdapter.startUpdate(container);
        }

        int getVirtualPosition(int realPosition) {
            return realPosition % mPagerAdapter.getCount();
        }

        PagerAdapter getPagerAdapter() {
            return mPagerAdapter;
        }

    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="180dp">
    </android.support.v4.view.ViewPager>

</RelativeLayout>

row_item_viewpager.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:gravity="center">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/txtItem"
        android:textAppearance="@android:style/TextAppearance.Large"/>

</LinearLayout>

Выполнено

2 голосов
/ 08 февраля 2014

Скелет адаптера бесконечного слайдера на основе предыдущих образцов

некоторые критические проблемы:

  • запомните исходную (относительную) позицию в представлении страницы (тег, использованный в образце), поэтому мы рассмотрим эту позицию, чтобы определить относительную позицию представления. в противном случае дочерний порядок в пейджере смешан
  • должен заполнить первый раз абсолютный вид внутри адаптера. (в остальное время эта заливка будет недействительной) не найдено способа принудительно заполнить ее из обработчика пейджера. остальные абсолютные значения времени будут переопределены из обработчика пейджера с правильными значениями.
  • когда страницы скользят быстро, боковая страница (фактически слева) не заполняется из обработчика пейджера. на данный момент обходного пути нет, просто используйте пустой вид, он будет заполнен фактическими значениями, когда перетаскивание остановлено. обн: быстрый обходной путь: отключить уничтожение элемента адаптера.

вы можете посмотреть на logcat, чтобы понять, что происходит в этом примере

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/calendar_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:padding="5dp"
        android:layout_gravity="center_horizontal"
        android:text="Text Text Text"
    />

</RelativeLayout>

А потом:

public class ActivityCalendar extends Activity
{
    public class CalendarAdapter extends PagerAdapter
    {
        @Override
        public int getCount()
        {
            return 3;
        }

        @Override
        public boolean isViewFromObject(View view, Object object)
        {
            return view == ((RelativeLayout) object);
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position)
        {
            LayoutInflater inflater = (LayoutInflater)ActivityCalendar.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View viewLayout = inflater.inflate(R.layout.layout_calendar, container, false);
            viewLayout.setTag(new Integer(position));

            //TextView tv = (TextView) viewLayout.findViewById(R.id.calendar_text);
            //tv.setText(String.format("Text Text Text relative: %d", position));

            if (!ActivityCalendar.this.scrolledOnce)
            {
                // fill here only first time, the rest will be overriden in pager scroll handler
                switch (position)
                {
                    case 0:
                        ActivityCalendar.this.setPageContent(viewLayout, globalPosition - 1);
                        break;
                    case 1:
                        ActivityCalendar.this.setPageContent(viewLayout, globalPosition);
                        break;
                    case 2:
                        ActivityCalendar.this.setPageContent(viewLayout, globalPosition + 1);
                        break;
                }
            }

            ((ViewPager) container).addView(viewLayout);

            //Log.i("instantiateItem", String.format("position = %d", position));

            return viewLayout;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object)
        {
            ((ViewPager) container).removeView((RelativeLayout) object);

            //Log.i("destroyItem", String.format("position = %d", position));
        }
    }

    public void setPageContent(View viewLayout, int globalPosition)
    {
        if (viewLayout == null)
            return;
        TextView tv = (TextView) viewLayout.findViewById(R.id.calendar_text);
        tv.setText(String.format("Text Text Text global %d", globalPosition));
    }

    private boolean scrolledOnce = false;
    private int focusedPage = 0;
    private int globalPosition = 0;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_calendar);

        final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);

        viewPager.setOnPageChangeListener(new OnPageChangeListener()
        {
            @Override
            public void onPageSelected(int position)
            {
                focusedPage = position;
                // actual page change only when position == 1
                if (position == 1)
                    setTitle(String.format("relative: %d, global: %d", position, globalPosition));
                Log.i("onPageSelected", String.format("focusedPage/position = %d, globalPosition = %d", position, globalPosition));
            }

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
            {
                //Log.i("onPageScrolled", String.format("position = %d, positionOffset = %f", position, positionOffset));
            }

            @Override
            public void onPageScrollStateChanged(int state)
            {
                Log.i("onPageScrollStateChanged", String.format("state = %d, focusedPage = %d", state, focusedPage));
                if (state == ViewPager.SCROLL_STATE_IDLE)
                {
                    if (focusedPage == 0)
                        globalPosition--;
                    else if (focusedPage == 2)
                        globalPosition++;

                    scrolledOnce = true;

                    for (int i = 0; i < viewPager.getChildCount(); i++)
                    {
                        final View v = viewPager.getChildAt(i);
                        if (v == null)
                            continue;

                        // reveal correct child position
                        Integer tag = (Integer)v.getTag();
                        if (tag == null)
                            continue;

                        switch (tag.intValue())
                        {
                            case 0:
                                setPageContent(v, globalPosition - 1);
                                break;
                            case 1:
                                setPageContent(v, globalPosition);
                                break;
                            case 2:
                                setPageContent(v, globalPosition + 1);
                                break;
                        }
                    }

                    Log.i("onPageScrollStateChanged", String.format("globalPosition = %d", globalPosition));

                    viewPager.setCurrentItem(1, false);
                }
            }
        });

        CalendarAdapter calendarAdapter = this.new CalendarAdapter();
        viewPager.setAdapter(calendarAdapter);

        // center item
        viewPager.setCurrentItem(1, false);
    }
}
0 голосов
/ 26 декабря 2018

На основании https://github.com/antonyt/InfiniteViewPager Я написал это, что хорошо работает:

class InfiniteViewPager @JvmOverloads constructor(
  context: Context,
  attrs: AttributeSet? = null
) : ViewPager(context, attrs) {
  // Allow for 100 back cycles from the beginning.
  // This should be enough to create an illusion of infinity.
  // Warning: scrolling to very high values (1,000,000+) results in strange drawing behaviour.
  private val offsetAmount get() = if (adapter?.count == 0) 0 else (adapter as InfinitePagerAdapter).realCount * 100

  override fun setAdapter(adapter: PagerAdapter?) {
    super.setAdapter(if (adapter == null) null else InfinitePagerAdapter(adapter))
    currentItem = 0
  }

  override fun setCurrentItem(item: Int) = setCurrentItem(item, false)

  override fun setCurrentItem(item: Int, smoothScroll: Boolean) {
    val adapterCount = adapter?.count

    if (adapterCount == null || adapterCount == 0) {
      super.setCurrentItem(item, smoothScroll)
    } else {
      super.setCurrentItem(offsetAmount + item % adapterCount, smoothScroll)
    }
  }

  override fun getCurrentItem(): Int {
    val adapterCount = adapter?.count

    return if (adapterCount == null || adapterCount == 0) {
      super.getCurrentItem()
    } else {
      val position = super.getCurrentItem()
      position % (adapter as InfinitePagerAdapter).realCount
    }
  }

  fun animateForward() {
    super.setCurrentItem(super.getCurrentItem() + 1, true)
  }

  fun animateBackwards() {
    super.setCurrentItem(super.getCurrentItem() - 1, true)
  }

  internal class InfinitePagerAdapter(private val adapter: PagerAdapter) : PagerAdapter() {
    internal val realCount: Int get() = adapter.count

    override fun getCount() = if (realCount == 0) 0 else Integer.MAX_VALUE

    override fun instantiateItem(container: ViewGroup, position: Int) = adapter.instantiateItem(container, position % realCount)

    override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) = adapter.destroyItem(container, position % realCount, `object`)

    override fun finishUpdate(container: ViewGroup) = adapter.finishUpdate(container)

    override fun isViewFromObject(view: View, `object`: Any) = adapter.isViewFromObject(view, `object`)

    override fun restoreState(bundle: Parcelable?, classLoader: ClassLoader?) = adapter.restoreState(bundle, classLoader)

    override fun saveState(): Parcelable? = adapter.saveState()

    override fun startUpdate(container: ViewGroup) = adapter.startUpdate(container)

    override fun getPageTitle(position: Int) = adapter.getPageTitle(position % realCount)

    override fun getPageWidth(position: Int) = adapter.getPageWidth(position)

    override fun setPrimaryItem(container: ViewGroup, position: Int, `object`: Any) = adapter.setPrimaryItem(container, position, `object`)

    override fun unregisterDataSetObserver(observer: DataSetObserver) = adapter.unregisterDataSetObserver(observer)

    override fun registerDataSetObserver(observer: DataSetObserver) = adapter.registerDataSetObserver(observer)

    override fun notifyDataSetChanged() = adapter.notifyDataSetChanged()

    override fun getItemPosition(`object`: Any) = adapter.getItemPosition(`object`)
  }
}

Для использования просто измените ViewPager на InfiniteViewPager, и это все, что вам нужно изменить.

0 голосов
/ 15 июня 2017

Я создал библиотеку, которая может создавать любой ViewPager, pagerAdapter (или FragmentStatePagerAdapter) и необязательный TabLayout для бесконечной прокрутки.

https://github.com/memorex386/infinite-scroll-viewpager-w-tabs

0 голосов
/ 01 мая 2014

Для бесконечной прокрутки по дням важно, чтобы у вас был хороший фрагмент в пейджере, поэтому я написал свой ответ об этом на странице ( Viewpager в Android для бесконечного переключения между днями )

Работает очень хорошо! Приведенные выше ответы не сработали для меня, так как я хотел, чтобы это сработало.

...