web-dev-qa-db-fra.com

RecyclerView notifyDataSetChanged fait défiler vers le haut

lorsque vous appelez notifyDataSetChanged sur RecyclerView, il ne conserve pas la position de défilement et défile vers le haut. Existe-t-il une solution permettant de conserver sa position de défilement?

12
Mohamed Hatem Abdu

Si le parent de l'élément de liste RecyclerView a la propriété "wrap_content", Recyclerview calcule à nouveau les hauteurs et fait défiler vers le haut.

Il y a deux solutions:

  1. Définissez votre taille avec une valeur constante comme ceci: layout_height="100dp"
  2. Utilisez StaggeredGridLayoutManager comme ceci:

    mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL));

La deuxième solution est plus efficace et je suggère celle-ci

12
serefakyuz

Je ne sais pas si cela résoudra votre problème, mais j’avais le même problème et c’est parce que j’appelais setAdapter après notify. Donc, ne pas appeler setAdapter après notification a résolu le problème.

mAdapter.notifyItemRangeInserted(mAdapter.getItemCount(), list.size() - 1);
recyclerView.setAdapter(); // remove this line. 
//Do this only when you're setting the data for the first time or when adapter is null. 
5
user3354265

Comme je le suppose, ce que vous faites est de réinitialiser l’adaptateur sur RecyclerView, puis d’appeler notifyDataSetChanged()..

Vous devez ne transmettre que la variable dataList à l'adaptateur en transmettant dataList à une méthode d'adaptateur telle que adapter update(dataList). . Cette méthode vous permet d'affecter cette liste à la liste d'adaptateurs telle que;

public void update(ArrayList<Hashmap<String,String> list){
  this.mList = list;
}
1
Sandy

Dans mon cas, le recyclage a été paginé. Chaque fois qu'il atteint la fin et charge/insère un élément à l'aide de notifyItemInserted, le recyclerView utilisé pour faire défiler. Ce qui suit a fonctionné pour moi:

recycler_view.stopScroll(); 

Comme indiqué dans le doc:

Arrête tout défilement en cours, tel que celui lancé par SmoothScrollBy (int, int), fling (int, int) ou un fling à l'initiative du toucher.

1
Ritesh Karmare

RecycleViews reviendra au début de toute variante de notifyDataSetChanged si elle n’a pas de gestionnaire de disposition. Voici un exemple montrant comment en définir un.

recycleView.setLayoutManager(new LinearLayoutManager(context, OrientationHelper.VERTICAL, false));
1
Maxwell

vous pouvez conserver votre position en l'enregistrant avant notifyDataSetChanged, puis appeler le défilement régulier vers une position enregistrée.

final int currentVisibleItem = ((LinearLayoutManager) layourmanager).findFirstCompletelyVisibleItemPosition();
                           productListAdapter.notifyDataSetChanged();
                            Handler handler = new Handler();
                            handler.postDelayed(new Runnable() {
                                @Override
                                public void run() {

                    if(currentVisibleItem>-1 && currentVisibleItem<lstProducts.size())
                                    rv_products.scrollToPosition(currentVisibleItem);
                                }
                            }, 100);
0
Rajesh Nasit