J'utilise une RecyclerView
avec des vues hétérogènes à l'intérieur, comme on le voit dans ce tutoriel .
J'ai dans le RecyclerView des articles qui sont aussi des RecyclerViews. Trop difficile à imaginer? Supposons que je veuille copier la présentation du Play Store: Un grand RecyclerView avec une présentation linéaire verticale et rempli de nombreux éléments: applications uniques et carrousel d'applications.
Si l'élément à ajouter est la mise en page d'une seule application, l'ID 1 sera utilisé et j'ajouterai la mise en page d'un seul élément . Sinon, si j'ai besoin d'ajouter un carrousel, je vais ajouter un élément à l'élément principal RecyclerView: Un autre RecyclerView avec son propre adaptateur.
Ça marche très bien. Sauf lorsque vous faites défiler le RecyclerView principal. Pourquoi? Parce que certaines vues sont détruites lorsqu'elles ne sont plus visibles, puis recréées dans la méthode onBindViewHolder()
. Pourquoi ici? Parce que l'adaptateur de RecyclerView principal passe pour la position X et appelle ensuite OnBindViewHolder()
. Ce dernier crée alors un nouveau RecyclerView avec son propre adaptateur et l’assigne. J'aimerais garder ces points de vue simplement parce qu'ils sont lourds à regonfler à chaque fois.
Est-ce possible? Si oui, pouvez-vous me dire comment?
Utilisez ceci:
recyclerView.getRecycledViewPool().setMaxRecycledViews(TYPE_CAROUSEL, 0);
Ce ne sera pas recycler une vue viewType TYPE_CAROUSEL
mais si le nombre d'éléments de ce type est très élevé, il réduira vos performances de manière significative, peut-être même causer Oomes
MODIFIER
Après avoir lu la réponse de MML13, je pense que cela pourrait fonctionner pour vous. Vous êtes inquiet au sujet des articles de votre carrousel étant regonflé lorsque ce point de vue est rebinded dans RecyclerView extérieur. Si tous ces sont de carrousel pour un même type, à savoir, ils utilisent tous même adaptateur, vous pouvez garder l'adaptateur à l'intérieur de ViewHolder RecyclerView extérieur, et juste échanger les données et appeler notifyDataSetChanged()
ou notifyItemRangeChanged(...)
sur cet adaptateur quand il est rebinded. Cela recyclera toutes les vues du carrousel et toutes les vues à l'intérieur de ces carrousels.
Vous pouvez également définir le code ci-dessous dans votre méthode d'adaptateur onBindViewholder ().
holder.setIsRecyclable(false);
J'ai pris référence à ce lien
http://aphoe.com/blog/prevent-androids-recyclerview-recycling-views/
Parce que certaines vues sont détruites quand elles ne sont plus visibles et ensuite recréé dans la méthode onBindViewHolder ().
Ce n'est pas vrai, ils ne sont pas créés à nouveau, ils se rebindent. si vous avez une vue pour la position X (dans la ferraille ou le recycleur) RecyclerView
l'utilisera et la reliera.
J'aimerais garder ces points de vue simplement parce qu'ils sont lourds à regonfler à chaque fois.
La variable principale RecyclerView
les conserve pour vous. Il vous suffit de modifier les données de l’adaptateur de votre seconde RecyclerView
et d’appeler notifyDataSetChanged
. Stockez également votre deuxième adaptateur RecyclerView
dans la viewHolder
de votre RecyclerView
principale.
Vous pouvez ajouter dans votre adaptateur:
@Override
public void onBindViewHolder(final CommentViewHolder viewHolder, final int position) {
viewHolder.setIsRecyclable(false);
}
Indique au recycleur si cet article peut être recyclé. Les vues non recyclables ne seront pas réutilisées pour d'autres éléments jusqu'à ce que setIsRecyclable()
soit ultérieurement défini sur true. Les appels à setIsRecyclable()
doivent toujours être associés (un appel à setIsRecyclabe(false)
doit toujours être associé à un appel ultérieur à setIsRecyclable(true)
). Les paires d'appels peuvent être imbriquées, car l'état est compté en interne.
Mon code fonctionne pour la réinitialisation de l'interface utilisateur dans recycleview.
public class BooleanViewHolder extends BaseViewHolder<ConfigItemBoolean> {
private SwitchCompat configBoolean;
BooleanViewHolder(View view) {
super(view);
configBoolean = view.findViewById(R.id.enable_config_boolean);
configBoolean.setOnCheckedChangeListener((buttonView, isChecked) -> {
((ConfigItemBoolean) getItem(getAdapterPosition())).setValue(isChecked);
DataSet.mConfigDataSet.getConfigItemBooleanMap().put(configPairList.get(getAdapterPosition()).first, ((ConfigItemBoolean) getItem(getAdapterPosition())));
});
}
@Override
void bind(ConfigItemBoolean item, String key) {
configBoolean.setText(item.getDisplayName());
configBoolean.setChecked(item.isValue());
}
}