Mam RecyclerView z polem tekstowym TextView i krzyżowym przyciskiem ImageView. Mam przycisk poza widokiem recyklingu, który sprawia, że przycisk krzyżowy ImageView jest widoczny / zniknął.
Chcę usunąć element z widoku ponownego, po naciśnięciu przycisku krzyżowego elementów ImageView.
Mój 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);
}
}
}
Mój układ to:
<?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>
Jak mogę uzyskać coś takiego jak onClick działający dla mojego crossButton ImageView? Czy jest lepszy sposób? Może zmiana całego przedmiotu jednym kliknięciem w usunięcie elementu? Widok recyklingu przedstawia listę lokalizacji, które należy edytować. Wszelkie porady techniczne lub komentarze / sugestie dotyczące najlepszego wdrożenia będą bardzo mile widziane.
java
android
user-interface
android-recyclerview
selection
Dwadzieścia sto
źródło
źródło
Odpowiedzi:
Zrobiłem coś podobnego. W twoim
MyAdapter
:Mam nadzieję że to pomoże.
Edytować:
getPosition()
jest teraz przestarzała, użyjgetAdapterPosition()
zamiast tego.źródło
notifyItemRangeChanged(getPosition, mDataSet.size());
do odpowiedzi paradite po usunięciu elementu, aby wszystkie widoki poniżej usuniętego elementu odpowiednio się dopasowały.getPosition()
teraz jest on przestarzałynotifyItemRemoved(position)
nie wystarczyło.przede wszystkim należy usunąć pozycję z listy!
następnie:
źródło
jeśli nadal przedmiot nie został usunięty, użyj tej magicznej metody :)
Wersja Kotlin
źródło
Problem
RecyclerView
jest domyślnie nieświadomy zmian w Twoim zbiorze danych. Oznacza to, że za każdym razem, gdy usuniesz / dodasz do swojej listy danych, zmiany te nie zostaną odzwierciedlone bezpośrednio w RecyclerView.Rozwiązanie
RecyclerView oferuje kilka metod udostępniania stanu zbioru danych. Dzieje się tak, ponieważ modyfikacja zbioru danych nie oznacza zmiany widoku i na odwrót. Standardowe API dla Androida pozwalają powiązać proces usuwania danych (na potrzeby pytania) z procesem usuwania widoku.
Najlepsze podejście
Jeśli nie określisz prawidłowo, co dzieje się podczas dodawania / usuwania elementów (mówienie o widokach), elementy podrzędne RecyclerView są animowane bez odpowiedzi z powodu braku informacji o tym, jak przesuwać różne widoki na liście.
Zamiast tego poniższy kod precyzyjnie odtworzy animację, tylko na usuwanym dziecku (I na marginesie, dla mnie naprawił wszystkie
IndexOutOfBoundException
s, oznaczone przez ślad stosu jako "niespójność danych")Pod maską, jeśli przyjrzymy się
RecyclerView
, możemy znaleźć dokumentację wyjaśniającą, że drugim parametrem, który musimy przekazać, jest liczba pozycji, które są usuwane ze zbioru danych, a nie całkowita liczba pozycji (jak błędnie stwierdzono w niektórych innych źródłach informacji).źródło
Prawdopodobnie podwójna odpowiedź, ale dla mnie całkiem przydatna. Możesz zaimplementować metodę podaną poniżej
RecyclerView.Adapter<RecyclerView.ViewHolder>
i możesz użyć tej metody zgodnie ze swoimi wymaganiami, mam nadzieję, że zadziała dla Ciebieźródło
Oto kilka wizualnych przykładów uzupełniających. Zobacz moją pełniejszą odpowiedź na przykłady dodawania i usuwania zakresu.
Dodaj pojedynczy element
Dodaj „Pig” w indeksie
2
.Usuń pojedynczy element
Usuń „Pig” z listy.
źródło
Wypróbowałem wszystkie powyższe odpowiedzi, ale wstawianie lub usuwanie elementów do recyclinglerview powoduje problem z pozycją w dataSet. Skończyło się na użyciu
delete(getAdapterPosition());
wewnątrz elementu viewHolder, który świetnie sprawdzał się w znajdowaniu pozycji przedmiotów.źródło
Problem, jaki miałem, polegał na tym, że usuwałem element z listy, który nie był już powiązany z adapterem, aby upewnić się, że modyfikujesz właściwy adapter, możesz zaimplementować taką metodę w swoim adapterze:
I nazwij to w swoim fragmencie lub działaniu w ten sposób:
źródło
mam nadzieję, że to ci pomoże.
źródło
jeśli chcesz usunąć przedmiot, powinieneś to zrobić: najpierw usuń przedmiot:
w następnym kroku należy powiadomić adapter recyklera o usunięciu elementu za pomocą tego kodu:
ale jeśli zmienisz element, zrób to: najpierw zmień parametr swojego obiektu w ten sposób:
lub nowy w ten sposób:
następnie powiadom swój adapter recyklera, że modyfikujesz element za pomocą tego kodu:
nadzieja pomaga.
źródło
źródło
notifyItemRemoved(position)
.Metoda
onBindViewHolder
Napisz ten kodźródło
Incase Każdy chce zaimplementować coś takiego w klasie Main zamiast w klasie Adapter, możesz użyć:
gdzie friendsListRecycler to nazwa adaptera
źródło
źródło
przekształcić interfejs w niestandardową klasę adaptera i obsługiwać zdarzenie kliknięcia w widoku recyklera.
po zdefiniowaniu adaptera i powiązaniu z widokiem recyklera o nazwie poniższy kod.
źródło
W przypadku, gdy zastanawiasz się, tak jak ja, gdzie możemy znaleźć pozycję adaptera w metodzie getadapterposition (); jest w obiekcie viewholder. więc musisz umieścić swój kod w ten sposób
źródło
źródło