J'essaie d'actualiser un élément spécifique dans RecyclerView
.
Histoire: Chaque fois que l'utilisateur clique sur un élément, il affiche AlertDialog
. L'utilisateur peut taper du texte en cliquant sur le bouton ok. Je souhaite afficher ce texte dans cet élément et afficher invisible ImageView
- déclarée en XML et adaptateur ViewHolder
-
J'ai utilisé cette fonction dans AlertDialog
Positive Button pour mettre à jour l'élément:
private void updateListItem(int position) {
View view = layoutManager.findViewByPosition(position);
ImageView medicineSelected = (ImageView) view.findViewById(R.id.medicine_selected);
medicineSelected.setVisibility(View.VISIBLE);
TextView orderQuantity = (TextView) view.findViewById(R.id.order_quantity);
orderQuantity.setVisibility(View.VISIBLE);
orderQuantity.setText(quantity + " packet added!");
medicinesArrayAdapter.notifyItemChanged(position);
}
Mais ce code modifie non seulement l'itemView à la position passée, mais modifie également certains autres itemView (s)!
Comment dois-je modifier un item spécifique correctement en cliquant dessus?
Vous pouvez utiliser la méthode notifyItemChanged(int position)
de la classe RecyclerView.Adapter. De la documentation:
Avertissez tous les observateurs inscrits que l'élément à la position a changé . Équivalent à appeler notifyItemChanged (position, null) ;.
Ceci est un événement de changement d'élément, pas un événement de changement structurel. Il indique que toute réflexion des données à la position est obsolète et devrait être mis à jour. L'élément en position conserve la même identité.
Comme vous avez déjà le poste, cela devrait fonctionner pour vous.
notifyItemChanged(updateIndex)
Modifiez l'élément "Moutons" afin qu'il indique "J'aime les moutons"
String newValue = "I like sheep.";
int updateIndex = 3;
data.set(updateIndex, newValue);
adapter.notifyItemChanged(updateIndex);
Ma réponse complète avec plus d'exemples est ici .
Je dois résoudre ce problème en identifiant la position de l'élément à modifier, puis dans l'appel de l'adaptateur.
public void refreshBlockOverlay(int position) {
notifyItemChanged(position);
}
, cela appellera onBindViewHolder (détenteur de ViewHolder, position int) pour cet élément spécifique à cette position spécifique.
Je pense avoir une idée sur la façon de gérer cela. La mise à jour est la même chose que la suppression et le remplacement à la position exacte. Donc, je supprime d'abord l'article de cette position en utilisant le code ci-dessous:
public void removeItem(int position){
mData.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mData.size());
}
et puis j'ajouterais l'article à cette position particulière, comme indiqué ci-dessous:
public void addItem(int position, Landscape landscape){
mData.add(position, landscape);
notifyItemInserted(position);
notifyItemRangeChanged(position, mData.size());
}
J'essaie de mettre cela en œuvre maintenant. Je voudrais vous donner un retour quand je suis à travers!
Dans votre classe d'adaptateur, dans la méthode onBindViewHolder, définissez ViewHolder sur setIsRecyclable (false) comme dans le code ci-dessous.
@Override
public void onBindViewHolder(RecyclerViewAdapter.ViewHolder p1, int p2)
{
// TODO: Implement this method
p1.setIsRecyclable(false);
// Then your other codes
}
La solution ci-dessous a fonctionné pour moi:
Sur un élément RecyclerView, l'utilisateur cliquera sur un bouton mais une autre vue, telle que TextView, sera mise à jour sans notifier directement l'adaptateur:
J'ai trouvé une bonne solution pour cela sans utiliser la méthode notifyDataSetChanged (), cette méthode recharge toutes les données de recyclerView. Ainsi, si vous avez une image ou une vidéo dans l'élément, elles seront rechargées et l'expérience utilisateur ne sera pas satisfaisante:
Voici un exemple de clic sur une icône semblable à ImageView et de mettre à jour un seul TextView (Possibilité de mettre à jour plusieurs vues de la même manière) pour afficher le nombre de mises à jour après avoir ajouté +1:
// View holder class inside adapter class
public class MyViewHolder extends RecyclerView.ViewHolder{
ImageView imageViewLike;
public MyViewHolder(View itemView) {
super(itemView);
imageViewLike = itemView.findViewById(R.id.imageViewLike);
imageViewLike.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = getAdapterPosition(); // Get clicked item position
TextView tv = v.getRootView().findViewById(R.id.textViewLikeCount); // Find textView of recyclerView item
resultList.get(pos).setLike(resultList.get(pos).getLike() + 1); // Need to change data list to show updated data again after scrolling
tv.setText(String.valueOf(resultList.get(pos).getLike())); // Set data to TextView from updated list
}
});
}
Une façon qui a fonctionné pour moi personnellement est d'utiliser les méthodes d'adaptateur de recyclerview pour gérer les modifications apportées à ses éléments.
Cela ressemblerait à ceci, créez une méthode dans la vue de votre recycleur personnalisé un peu comme ceci:
public void modifyItem(final int position, final Model model) {
mainModel.set(position, model);
notifyItemChanged(position);
}
Ajoutez le texte modifié à votre liste de données de modèle
mdata.get(position).setSuborderStatusId("5");
mdata.get(position).setSuborderStatus("cancelled");
notifyItemChanged(position);
si vous créez un objet et que vous l'ajoutez à la liste que vous utilisez dans votre adaptateur, lorsque vous modifiez un élément de votre liste dans l'adaptateur, tous vos autres éléments changent également, autrement dit, il s'agit uniquement de références et votre liste ne le fait pas. détenir des copies séparées de cet objet unique.
il vous suffit d'ajouter le code suivant dans la boîte de dialogue d'alerte lors de l'enregistrement, cliquez sur
recyclerData.add(position, updateText.getText().toString());
recyclerAdapter.notifyItemChanged(position);