web-dev-qa-db-fra.com

Mise à jour partielle de RecyclerView.ViewHolder

J'essaie de changer le champ avec le temps dans mon RecyclerView. Chaque ViewHolder individuel contient un CardView et quelques autres vues à l'intérieur. La seule vue que je veux animer est celle avec le temps. Comme vous pouvez le voir, il n'y a pas d'animation:

adapter.notifyDataSetChanged();

RecyclerView with no animations

La mise à jour des éléments un par un n'aide pas car alors l'ensemble CardView clignote:

int len = adapter.getItemCount();
for(int i=0;i<len;i++) {
    adapter.notifyItemChanged(i);
}

enter image description here

Existe-t-il un moyen d'obtenir une liste de tous les ViewHolders pour ensuite mettre à jour (animer) celui-là TextView à l'intérieur de chacun?

28
PhpXp

Vous pouvez informer les observateurs de votre RecyclerView.Adapter De publier une mise à jour partielle de votre RecyclerView.ViewHolders En transmettant une charge utile Object.

notifyItemRangeChanged(positionStart, itemCount, payload);

payload pourrait être ou contenir un indicateur qui représente le temps relatif ou absolu. Pour lier le payload à vos détenteurs de vue, remplacez la méthode onBindViewHolder(viewHolder, position, payloads) suivante dans votre adaptateur et vérifiez le paramètre payloads pour les données.

@Override
public void onBindViewHolder(MyViewHolder viewHolder, int position, List<Object> payloads) {
    if (payloads.isEmpty()) {
        // Perform a full update
        onBindViewHolder(viewHolder, position);
    } else {
        // Perform a partial update
        for (Object payload : payloads) {
            if (payload instanceof TimeFormatPayload) {
                viewHolder.bindTimePayload((TimeFormatPayload) payload);
            }
        }
    }
}

Dans votre méthode MyViewHolder.bindTimePayload(payload), mettez à jour votre heure TextViews au format d'heure spécifié dans payload.

55
Ryan