web-dev-qa-db-fra.com

Comment créer un RecyclerView circulaire (sans fin)?

J'essaie de faire ma boucle RecyclerView au début de ma liste.

J'ai cherché partout sur Internet et j'ai réussi à détecter le moment où j'ai atteint la fin de ma liste, mais je ne sais pas par où commencer.

C'est ce que j'utilise actuellement pour détecter la fin de la liste (trouvé ici ):

 @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

        visibleItemCount = mLayoutManager.getChildCount();
        totalItemCount = mLayoutManager.getItemCount();
        pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();

        if (loading) {
            if ( (visibleItemCount+pastVisiblesItems) >= totalItemCount) {
                loading = false;
                Log.v("...", ""+visibleItemCount);
            }
        }
 }

Lorsque je fais défiler l'écran jusqu'au bout, j'aimerais que les vues soient visibles tout en affichant les données du haut de la liste ou lorsque je les fais défiler en haut de la liste, je voudrais afficher les données du bas de la liste.

Par exemple:

Voir1 Voir2 Voir3 Voir4 Voir5

Voir5 Voir1 Voir2 Voir3 Voir4

27
ltsai

Il n'y a aucun moyen de le rendre infini, mais il y a un moyen de le faire ressembler à l'infini.

  1. dans votre adaptateur, remplacez getCount() pour renvoyer quelque chose de grand comme Integer.MAX_VALUE:

    @Override
    public int getCount() {
        return Integer.MAX_VALUE;
    }
    
  2. dans getItem() et getView() modulo divide (%) position par numéro d'article réel:

    @Override
    public Fragment getItem(int position) {
        int positionInList = position % fragmentList.size();
        return fragmentList.get(positionInList);
    }
    
  3. à la fin, définissez l'élément en cours sur quelque chose au milieu (sinon, il serait sans fin seulement dans le sens descendant).

    // scroll to middle item
    recyclerView.getLayoutManager().scrollToPosition(Integer.MAX_VALUE / 2);
    
56
Sebastian Pakieła

Les autres solutions que j'ai trouvées pour résoudre ce problème fonctionnent assez bien, mais je pense qu'il peut y avoir des problèmes de mémoire qui renvoient Integer.MAX_VALUE dans la méthode getCount () de la vue Recycler.

Pour résoudre ce problème, substituez la méthode getItemCount () comme ci-dessous:

@Override
public int getItemCount() {
    return itemList == null ? 0 : itemList.size() * 2;
}

Maintenant, partout où vous utilisez la position pour obtenir l'élément de la liste, utilisez ci-dessous

position % itemList.size()

Maintenant, ajoutez scrollListener à votre vue recycleur

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) 
        super.onScrolled(recyclerView, dx, dy);
        int firstItemVisible = linearLayoutManager.findFirstVisibleItemPosition();
        if (firstItemVisible != 0 && firstItemVisible % itemList.size() == 0) {
            recyclerView.getLayoutManager().scrollToPosition(0);
        }
    }
});

Enfin, pour lancer le défilement automatique, appelez la méthode ci-dessous

public void autoScroll() {
    final Handler handler = new Handler();
    final Runnable runnable = new Runnable() {
        @Override
        public void run() {
            recyclerView.scrollBy(2, 0);
            handler.postDelayed(this, 0);
        }
    };
    handler.postDelayed(runnable, 0);
}
13
Nikhil Gupta

En plus de la solution ci-dessus . Pour une vue illimitée du recycleur des deux côtés, vous devriez ajouter quelque chose comme ça:

recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
        override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
            super.onScrolled(recyclerView, dx, dy)
            val firstItemVisible = linearLayoutManager.findFirstVisibleItemPosition()
            if (firstItemVisible != 1 && firstItemVisible % songs.size == 1) {
                linearLayoutManager.scrollToPosition(1)
            }
            val firstCompletelyItemVisible = linearLayoutManager.findFirstCompletelyVisibleItemPosition()
            if (firstCompletelyItemVisible == 0) {
                linearLayoutManager.scrollToPositionWithOffset(songs.size, 0)
            }
        }
    })

Et mettez à niveau votre méthode getItemCount ():

@Override
public int getItemCount() {
        return itemList == null ? 0 : itemList.size() * 2 + 1;
}

C'est un travail comme le défilement illimité, mais dans les deux sens. Heureux de vous aider!

0
afanit