Ich versuche, ein bestimmtes Element in RecyclerView
zu aktualisieren.
Story: Wenn ein Benutzer auf ein Element klickt, wird AlertDialog
angezeigt. Der Benutzer kann Text eingeben, indem er auf die Schaltfläche OK klickt. Ich möchte diesen Text in diesem Element anzeigen und unsichtbar ImageView
- in XML und Adapter ViewHolder
- deklariert anzeigen.
Ich habe diese Funktion in AlertDialog
Positive Button verwendet, um das Element zu aktualisieren:
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);
}
Dieser Code ändert jedoch nicht nur die itemView an der übergebenen Position, sondern auch einige andere ItemView (s)!
Wie kann ich eine bestimmte itemView korrekt ändern, indem Sie darauf klicken?
Sie können die Methode notifyItemChanged(int position)
aus der RecyclerView.Adapter-Klasse verwenden. Aus der Dokumentation:
Benachrichtigen Sie alle registrierten Beobachter darüber, dass sich der Artikel an der Position geändert hat . Entspricht dem Aufruf von notifyItemChanged (position, null) ;.
Dies ist ein Elementänderungsereignis, kein Strukturänderungsereignis. Es zeigt an, dass die Spiegelung der Daten an der Position nicht mehr aktuell ist und sollte aktualisiert werden. Der Artikel an Position behält die gleiche Identität.
Da Sie die Position bereits haben, sollte es für Sie funktionieren.
notifyItemChanged(updateIndex)
Ändern Sie das Element "Schaf" so, dass "Ich mag Schafe" sagt
String newValue = "I like sheep.";
int updateIndex = 3;
data.set(updateIndex, newValue);
adapter.notifyItemChanged(updateIndex);
Meine vollständige Antwort mit weiteren Beispielen ist hier .
Ich konnte dieses Problem lösen, indem ich die Position des Elements, das geändert werden musste, erwischte und anschließend im Adapteraufruf
public void refreshBlockOverlay(int position) {
notifyItemChanged(position);
}
Dies ruft onBindViewHolder (ViewHolder-Inhaber, int-Position) für diesen bestimmten Artikel an dieser bestimmten Position auf.
Ich denke, ich habe eine Idee, wie ich damit umgehen soll. Das Aktualisieren entspricht dem Löschen und Ersetzen an der genauen Position. Also entferne ich den Artikel zuerst von dieser Position mit dem folgenden Code:
public void removeItem(int position){
mData.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mData.size());
}
und dann würde ich den Artikel an dieser bestimmten Position hinzufügen, wie unten gezeigt:
public void addItem(int position, Landscape landscape){
mData.add(position, landscape);
notifyItemInserted(position);
notifyItemRangeChanged(position, mData.size());
}
Ich versuche das jetzt umzusetzen. Ich würde dir ein Feedback geben, wenn ich fertig bin!
Setzen Sie in Ihrer Adapterklasse in der Methode onBindViewHolder ViewHolder wie im folgenden Code auf setIsRecyclable (false).
@Override
public void onBindViewHolder(RecyclerViewAdapter.ViewHolder p1, int p2)
{
// TODO: Implement this method
p1.setIsRecyclable(false);
// Then your other codes
}
Die folgende Lösung hat für mich funktioniert:
Bei einem RecyclerView-Element wird der Benutzer auf eine Schaltfläche klicken, eine andere Ansicht wie TextView wird jedoch aktualisiert, ohne den Adapter direkt zu benachrichtigen:
Ich habe eine gute Lösung dafür gefunden, ohne die Methode notifyDataSetChanged () zu verwenden. Diese Methode lädt alle Daten von recyclerView neu. Wenn Sie also ein Bild oder ein Video in item haben, werden sie neu geladen, und die Benutzererfahrung wird nicht gut sein:
Beispiel: Klicken Sie auf ein ImageView-Symbol und aktualisieren Sie nur eine einzelne TextView-Ansicht (möglich, weitere Ansicht auf dieselbe Weise in demselben Element zu aktualisieren), um nach dem Hinzufügen von +1 die Anzahl der Aktualisierungszähler anzuzeigen:
// 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
}
});
}
Ein Weg, der für mich persönlich funktioniert hat, ist die Verwendung der Adaptermethoden des Recyclerovers, um mit Änderungen an den Elementen umzugehen.
In ähnlicher Weise würde es so aussehen: Erstellen Sie in der Ansicht Ihres benutzerdefinierten Recyclers eine Methode, die etwa wie folgt aussieht:
public void modifyItem(final int position, final Model model) {
mainModel.set(position, model);
notifyItemChanged(position);
}
Fügen Sie den geänderten Text Ihrer Modelldatenliste hinzu
mdata.get(position).setSuborderStatusId("5");
mdata.get(position).setSuborderStatus("cancelled");
notifyItemChanged(position);
wenn Sie ein Objekt erstellen und es zu der Liste hinzufügen, die Sie in Ihrem Adapter verwenden, ändern sich auch alle anderen Elemente, wenn Sie ein Element Ihrer Liste im Adapter ändern, mit anderen Worten, es geht nur um Verweise und Ihre Liste nicht Halten Sie separate Kopien dieses einzelnen Objekts.
sie müssen lediglich den folgenden Code im Benachrichtigungsdialogfeld beim Speichern hinzufügen
recyclerData.add(position, updateText.getText().toString());
recyclerAdapter.notifyItemChanged(position);