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?
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:
layout_height="100dp"
Utilisez StaggeredGridLayoutManager comme ceci:
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL));
La deuxième solution est plus efficace et je suggère celle-ci
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.
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;
}
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.
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));
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);