web-dev-qa-db-fra.com

Modification de ViewPager pour activer le défilement infini de pages

Jon Willis a posté sur la façon de permettre un défilement infini avec son code . Il y a indiqué qu'il avait apporté quelques modifications à la classe ViewPager dans la bibliothèque de support Android. Quelles modifications ont été apportées et comment est-il possible de "recompiler" la bibliothèque avec la modification ViewPager?

41
thehayro

Merci pour votre réponse Shereef.

Je l'ai résolu un peu différemment.

J'ai changé le code de la classe ViewPager de la bibliothèque de support Android. La méthode setCurrentItem(int)

change la page avec animation. Cette méthode appelle une méthode interne qui requiert l'index et un indicateur permettant un défilement régulier. Cet indicateur est boolean smoothScroll. L'extension de cette méthode avec un deuxième paramètre boolean smoothScroll l'a résolu pour moi . Appeler cette méthode setCurrentItem(int index, boolean smoothScroll) m'a permis de le faire défiler indéfiniment.

Voici un exemple complet:

Veuillez considérer que seule la page centrale est affichée ..__ De plus, ai-je rangé les pages séparément, ce qui me permet de les manipuler plus facilement.

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);
            }
        }
    });

Cependant, sans Jon Willis Code, je ne l'aurais pas résolu moi-même. 

EDIT: voici un blogpost à ce sujet: 

32
thehayro

J'ai résolu ce problème très simplement en utilisant un petit bidouillage dans l'adaptateur. Voici mon code:

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;
        }
    }
} 

Et puis, dans ViewPager, nous plaçons la page en cours au milieu:

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
36
petrnohejl

Page infinie en repérant 4 méthodes d’adaptateur dans votre classe d’adaptateurs existante

    @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);
    }
30
Pawan Maheshwari

Il suffit de regarder l'exemple ici

Vous constaterez qu'à la ligne 295, la page est toujours définie sur 1 de sorte qu'elle défile Et que le nombre de pages est de 3 dans la méthode getCount().

Ce sont les 2 choses principales que vous devez changer, le reste est votre logique et vous pouvez les gérer différemment.

Créez simplement un compteur personnel qui compte la page réelle sur laquelle vous vous trouvez car la position ne sera plus utilisable après avoir toujours défini la page en cours à 1 sur la ligne 295.

p.s. ce code n'est pas le mien, il a été référencé dans la question que vous avez liée dans votre question

9
Shereef Marzouk

En fait, j’ai étudié les différentes façons de faire cette pagination "infinie", et même si la notion humaine du temps est qu’il est infini (même si nous avons une notion du début et de la fin des temps), les ordinateurs dans le discret. Il y a un temps minimum et maximum (qui peut être ajusté au fil du temps, rappelez-vous la base de la peur de l'an 2000?). 

Quoi qu’il en soit, le but de cette discussion est qu’il est/devrait être suffisant pour prendre en charge une plage de dates relativement infinie à travers une plage de dates réellement définie. Un bon exemple de ceci est l'implémentation CalendarView du framework Android et la WeeksAdapter qu'il contient. La date minimale par défaut est 1900 et la date maximale par défaut est 2100. Ceci devrait couvrir facilement 99% de l'utilisation du calendrier de toute personne se trouvant dans un rayon de 10 ans autour de la journée. 

Ce qu’ils font dans leur implémentation (centrée sur les semaines) est de calculer le nombre de semaines entre la date minimale et maximale. Cela devient le nombre de pages du pager. N'oubliez pas que le pager n'a pas besoin de gérer toutes ces pages simultanément (setOffscreenPageLimit(int)), il doit simplement pouvoir créer la page en fonction du numéro de page (ou de l'index/de la position). Dans ce cas, l'index est le nombre de semaines de la semaine depuis la date minimum. Avec cette approche, il vous suffit de conserver la date minimale et le nombre de pages (distance par rapport à la date maximale). Ensuite, pour toute page, vous pouvez facilement calculer la semaine associée à cette page. Pas question de danser sur le fait que ViewPager ne supporte pas la boucle (a.k. une pagination infinie), et d'essayer de le forcer à se comporter comme s'il pouvait défiler à l'infini.

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;
    }
};

Alors WeekDaysFragment peut facilement afficher la semaine à partir de la date passée dans ses arguments.

Alternativement, il semble qu'une version de l'application Agenda sous Android utilise une ViewSwitcher (ce qui signifie qu'il n'y a que 2 pages, celle que vous voyez et la page cachée). Il modifie ensuite l'animation de la transition en fonction de la manière dont l'utilisateur a balayé et affiche la page suivante/précédente en conséquence. De cette façon, vous obtenez une pagination infinie, car il vous suffit de basculer entre deux pages à l'infini. Cela nécessite l’utilisation de View pour la page, ce qui est le cas avec la première approche.

En général, si vous voulez une "pagination infinie", c'est probablement parce que vos pages sont basées sur des dates ou des heures. Si tel est le cas, envisagez plutôt d'utiliser un sous-ensemble fini de temps relativement infini. Voici comment CalendarView est implémenté. Ou vous pouvez utiliser l'approche ViewSwitcher. L’avantage de ces deux approches est qu’aucune des opérations particulièrement inhabituelles avec ViewSwitcher ou ViewPager ne fait rien, et ne nécessite aucune astuce ni aucune réimplémentation pour les forcer à se comporter indéfiniment (ViewSwitcher est déjà conçu pour basculer infiniment entre les vues, mais ViewPager est conçu pour travailler sur un ensemble de pages fini, mais pas nécessairement constant).

5
Dandre Allison

squelette d'adaptateur de curseur infini basé sur des exemples précédents

quelques problèmes critiques:

  • mémoriser la position d'origine (relative) dans la vue de page (balise utilisée dans l'exemple), nous allons donc regarder cette position pour définir la position de vue relative. sinon l'ordre dans le pager est mixte
  • doit remplir la première fois la vue absolue à l'intérieur de l'adaptateur. (le reste du temps, ce remplissage sera invalide) n'a trouvé aucun moyen de le forcer à se remplir à partir du gestionnaire de pager. la vue absolue des temps de repos sera remplacée par le gestionnaire de pageur avec les valeurs correctes.
  • lorsque les pages sont glissées rapidement, la page latérale (en fait, à gauche) n'est pas remplie par le gestionnaire de pager. pas de solution de contournement pour le moment, utilisez simplement une vue vide, elle sera remplie avec les valeurs réelles lorsque le glisser est arrêté. upd: solution de contournement rapide: désactive destroyItem de l'adaptateur.

vous pouvez regarder le logcat pour comprendre ce qui se passe dans cet exemple

<?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>

Et alors:

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);
    }
}
2
Dmitry Bryliuk

Son piraté par 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>

Terminé

2
Hiren Patel

Pour le défilement infini avec les jours, il est important que vous ayez le bon fragment dans le pager, c’est pourquoi j’ai écrit ma réponse sur cette page ( Viewpager dans Android pour basculer entre les jours )

Cela fonctionne très bien! Les réponses ci-dessus n'ont pas fonctionné pour moi car je voulais que cela fonctionne.

0

Basé sur https://github.com/antonyt/InfiniteViewPager J'ai écrit ceci qui fonctionne bien:

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`)
  }
}

Pour le consommer, changez simplement votre ViewPager en InfiniteViewPager et c’est tout ce que vous avez besoin de changer.

0
Niklas

J'ai construit une bibliothèque qui peut faire de n'importe quel ViewPager, pagerAdapter (ou FragmentStatePagerAdapter) et facultatif TabLayout Scrolling infiniment.

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

0
Brad