Ich habe eine RecyclerView mit einem TextView-Textfeld und einer Kreuzschaltfläche ImageView. Ich habe eine Schaltfläche außerhalb der Recycling-Ansicht, die die Kreuzschaltfläche ImageView sichtbar / verschwunden macht.
Ich möchte ein Element aus der Recylerview entfernen, wenn diese Elemente die Schaltfläche ImageView drücken.
Mein Adapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> implements View.OnClickListener, View.OnLongClickListener {
private ArrayList<String> mDataset;
private static Context sContext;
public MyAdapter(Context context, ArrayList<String> myDataset) {
mDataset = myDataset;
sContext = context;
}
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_text_view, parent, false);
ViewHolder holder = new ViewHolder(v);
holder.mNameTextView.setOnClickListener(MyAdapter.this);
holder.mNameTextView.setOnLongClickListener(MyAdapter.this);
holder.mNameTextView.setTag(holder);
return holder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.mNameTextView.setText(mDataset.get(position));
}
@Override
public int getItemCount() {
return mDataset.size();
}
@Override
public void onClick(View view) {
ViewHolder holder = (ViewHolder) view.getTag();
if (view.getId() == holder.mNameTextView.getId()) {
Toast.makeText(sContext, holder.mNameTextView.getText(), Toast.LENGTH_SHORT).show();
}
}
@Override
public boolean onLongClick(View view) {
ViewHolder holder = (ViewHolder) view.getTag();
if (view.getId() == holder.mNameTextView.getId()) {
mDataset.remove(holder.getPosition());
notifyDataSetChanged();
Toast.makeText(sContext, "Item " + holder.mNameTextView.getText() + " has been removed from list",
Toast.LENGTH_SHORT).show();
}
return false;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mNumberRowTextView;
public TextView mNameTextView;
public ViewHolder(View v) {
super(v);
mNameTextView = (TextView) v.findViewById(R.id.nameTextView);
}
}
}
Mein Layout ist:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:id="@+id/layout">
<TextView
android:id="@+id/nameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:padding="5dp"
android:background="@drawable/greyline"/>
<ImageView
android:id="@+id/crossButton"
android:layout_width="16dp"
android:layout_height="16dp"
android:visibility="gone"
android:layout_marginLeft="50dp"
android:src="@drawable/cross" />
</LinearLayout>
Wie kann ich so etwas wie einen onClick für mein crossButton ImageView zum Laufen bringen? Gibt es einen besseren Weg? Vielleicht ändern Sie den gesamten Artikel per Klick in einen Artikel entfernen? Die Recycling-Ansicht zeigt eine Liste der Speicherorte, die bearbeitet werden müssen. Alle technischen Ratschläge oder Kommentare / Vorschläge zur besten Implementierung wären sehr dankbar.
Antworten:
Ich habe etwas ähnliches gemacht. In Ihrem
MyAdapter
:Hoffe das hilft.
Bearbeiten:
getPosition()
ist jetzt veraltet, verwenden SiegetAdapterPosition()
stattdessen.quelle
notifyItemRangeChanged(getPosition, mDataSet.size());
die Antwort von paradite hinzufügen , nachdem Sie das Element entfernt haben, damit alle Ansichten unter dem entfernten Element entsprechend angepasst werden.getPosition()
ist aber jetzt veraltetnotifyItemRemoved(position)
war es nicht genug , nur anzurufen .Zunächst sollte das Element aus der Liste entfernt werden!
dann:
quelle
Wenn der Gegenstand immer noch nicht entfernt wurde, benutze diese magische Methode :)
Kotlin-Version
quelle
Problem
RecyclerView
ist standardmäßig nicht über Ihre Dataset-Änderungen informiert. Dies bedeutet, dass diese Änderungen bei jeder Löschung / Hinzufügung in Ihrer Datenliste nicht direkt in Ihrem RecyclerView übernommen werden.Lösung
RecyclerView bietet Ihnen einige Methoden zum Freigeben Ihres Dataset-Status. Dies liegt daran, dass eine Änderung an Ihrem Dataset keine Ansichtsänderung impliziert und umgekehrt. Mit den Standard-Android-APIs können Sie den Prozess der Datenentfernung (zum Zweck der Frage) mit dem Prozess der Ansichtsentfernung verknüpfen.
Bester Ansatz
Wenn Sie nicht richtig angeben, was beim Hinzufügen / Entfernen von Elementen geschieht (über Ansichten sprechen), werden RecyclerView-Kinder aufgrund fehlender Informationen zum Verschieben der verschiedenen Ansichten in der Liste nicht reagiert.
Stattdessen spielt der folgende Code die Animation genau auf dem Kind ab, das entfernt wird (und als Randnotiz hat er für mich alle
IndexOutOfBoundException
s behoben , die durch die Stapelverfolgung als "Dateninkonsistenz" gekennzeichnet sind).Wenn wir unter die Haube schauen,
RecyclerView
finden wir eine Dokumentation, die erklärt, dass der zweite Parameter, den wir übergeben müssen, die Anzahl der Elemente ist, die aus dem Datensatz entfernt werden, nicht die Gesamtzahl der Elemente (wie in einigen anderen Informationsquellen falsch angegeben).quelle
Möglicherweise eine doppelte Antwort, aber sehr nützlich für mich. Sie können die unten angegebene Methode in implementieren
RecyclerView.Adapter<RecyclerView.ViewHolder>
und diese Methode gemäß Ihren Anforderungen verwenden. Ich hoffe, dass sie für Sie funktioniertquelle
Hier sind einige visuelle Ergänzungsbeispiele. Siehe meine ausführlichere Antwort Beispiele zum Hinzufügen und Entfernen eines Bereichs.
Einzelteil hinzufügen
Fügen Sie "Schwein" am Index hinzu
2
.Einzelteil entfernen
Entfernen Sie "Schwein" aus der Liste.
quelle
Ich habe alle oben genannten Antworten ausprobiert, aber das Einfügen oder Entfernen von Elementen in recyclerview verursacht Probleme mit der Position im dataSet.
delete(getAdapterPosition());
Am Ende wurde der viewHolder verwendet, der sich hervorragend zum Finden der Position von Elementen eignet.quelle
Das Problem, das ich hatte, war, dass ich ein Element aus der Liste entfernt habe, das nicht mehr mit dem Adapter verknüpft war, um sicherzustellen, dass Sie den richtigen Adapter ändern. Sie können eine Methode wie diese in Ihrem Adapter implementieren:
Und nennen Sie es in Ihrem Fragment oder Ihrer Aktivität so:
quelle
Ich hoffe das hilft dir.
quelle
Wenn Sie ein Element entfernen möchten, sollten Sie Folgendes tun: Entfernen Sie zuerst das Element:
Im nächsten Schritt sollten Sie Ihren Recycler-Adapter darüber informieren, dass Sie einen Artikel mit diesem Code entfernen:
Wenn Sie jedoch ein Element ändern, gehen Sie folgendermaßen vor: Ändern Sie zuerst einen Parameter Ihres Objekts wie folgt:
oder neu so:
Benachrichtigen Sie dann Ihren Recycler-Adapter, dass Sie einen Artikel mit diesem Code ändern:
Hoffnung hilft dir.
quelle
quelle
notifyItemRemoved(position)
.Zur Methode
onBindViewHolder
Schreiben Sie diesen Codequelle
Falls jemand so etwas in der Hauptklasse anstelle der Adapterklasse implementieren möchte, können Sie Folgendes verwenden:
Dabei ist friendsListRecycler der Adaptername
quelle
quelle
Schnittstelle in benutzerdefinierte Adapterklasse umwandeln und Klickereignis in der Recycler-Ansicht behandeln.
Nachdem Sie den Adapter definiert und in die Recycler-Ansicht mit dem folgenden Code gebunden haben.
quelle
Falls Sie sich wie ich fragen, wo können wir die Adapterposition in der Methode getadapterposition () finden? Es befindet sich in viewholder object.so müssen Sie Ihren Code so einfügen
quelle
quelle