2015-07-15 12 views
6

W jaki sposób można uzyskać spójny wybór pozycji za pomocą RecyclerView? Rozumiem, że RecyclerView przetwarza stare widoki, a co nie. Mój problem polega na tym, że mam listę przedmiotów z ikoną na każdym przedmiocie, po kliknięciu elementu ikona zmienia kolor. Udało mi się to wszystko osiągnąć, ale po przewinięciu listy zauważyłem, że inne przedmioty również mają zmienione ikony, a kiedy przewijam do pozycji, którą kliknąłem, ikona nie jest już "kliknięta" kolor".Jak śledzić wybrane pozycje w RecyclerView w systemie Android?

Czy ktoś wie, jak śledzić wybrane elementy? Wciąż widzę coś o nazwie SparseBooleanArray, ale nie jestem pewien, jak to zaimplementować.

Oto mój kod adapter:

public class TableRVAdapter extends RecyclerView.Adapter<TableRVAdapter.TableHolder> { 

    List<Tables> tableList; 
    private SparseBooleanArray selectedItems; 

    public TableRVAdapter(List<Tables> tableList) 
    { 
     this.tableList = tableList; 
     selectedItems = new SparseBooleanArray(); 
     // setHasStableIds(true); 
    } 
    class TableHolder extends RecyclerView.ViewHolder 
    { 
     TextView tableTV; 
     CardView tableCV; 
     View circle; 
     View parentView; 
     TableHolder(final View itemView) 
     { 
      super(itemView); 
      tableTV = (TextView)itemView.findViewById(R.id.tableTV); 
      tableCV = (CardView)itemView.findViewById(R.id.tableCV); 
      circle = itemView.findViewById(R.id.statusCircle); 
      itemView.setClickable(true); 
      parentView = itemView; 

      tableCV.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        circle.setBackgroundResource(R.drawable.circle); 

       } 
      }); 
     } 
     /* 
     @Override 
     public void onClick(View view) { 
      if (selectedItems.get(getAdapterPosition(), false)) { 
       tableCV.setSelected(false); 
       circle.setBackgroundResource(R.drawable.circle2); 
      } 
      else { 
       selectedItems.put(getAdapterPosition(), true); 
       tableCV.setSelected(true); 
       circle.setBackgroundResource(R.drawable.circle); 
      } 

     }*/ 
    } 

    @Override 
    public TableHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.table_item,parent,false); 
     TableHolder tableHolder = new TableHolder(view); 
     return tableHolder; 
    } 

    @Override 
    public void onAttachedToRecyclerView(RecyclerView recyclerView) 
    { 
     super.onAttachedToRecyclerView(recyclerView); 
    } 


    @Override 
    public void onBindViewHolder(TableHolder holder, int position) { 
     holder.tableTV.setText(tableList.get(position).getTableNumber()); 

    } 

    /** 
    * Returns the total number of items in the data set hold by the adapter. 
    * 
    * @return The total number of items in this adapter. 
    */ 
    @Override 
    public int getItemCount() { 
     return tableList.size(); 
    } 

} 
+0

Zobacz mój zredagowany wpis – spongyboss

Odpowiedz

3

RecyclerView.adapter ma 2 ważne funkcje przesłonić:

onCreateViewHolder(parent, viewType) 
onBindVIewHolder(viewholder, position) 

Pierwsza funkcja służy do nadmuchiwania widoków, które będą używane wewnątrz widoku recyklingu, druga służy do wiązania danych, które masz do tego widoku, a tym samym ustawić poprawną stan wyświetlania w widoku.

Sam widok recyrkulatora spowoduje jedynie zwiększenie liczby wyświetleń, a następnie zacznie ponownie wykorzystywać już zawyżone widoki (stąd przegląd recyclerview). Musisz więc ustawić poprawny stan dla każdej pozycji w onBindViewholder() i użyć pozycji w kolekcji na tej pozycji, aby ustawić poprawne viewState. Na przykład: zmień kolor ikony, zależnie od wartości boolowskiej obiektów, np .: isPressed

+0

Dziękuję za to, proszę pana! i dziękuję za wyjaśnienie celu onBindViewHolder, udało mi się rozwiązać go po przeczytaniu twojego postu. Dzięki jeszcze raz – spongyboss

1

Musisz zapisać instancji jak ten

if (isPressed) { 
    icon.setCustomIcon(); 
} else { 
    icon.setDefaultIcon();  
} 

jeśli masz niestandardowego obiektu mieć wartość logiczną isPressed lub coś podobnego, to powinien pracować

4

Wiem, że to pytanie już zostało udzielone, ale ktoś może uznać tę odpowiedź za przydatną i łatwiejszą.

Jest jedna użyteczna metoda w widoku recyklera: onViewRecycled.

Pomoże ci to uciec od wciśniętego stanu. Podczas pracy z obrazami/rysunkami w widoku recylcera, gdy niektóre elementy nie używają rysunków, podgląd podglądu rysowanego widoku recyklera będzie obecny i sprawi, że wszystkie dane będą wyglądały niepoprawnie, tak jak to miało miejsce w przypadku wybranego widoku.

Aby to osiągnąć w prostszy sposób, możesz użyć tej metody, aby wyczyścić narysowane obrazy, aby zresetować ich wartości.

Na przykład oznaczyć wybrano elementu tła na zielono, a niektóre z widokiem zawiera zdjęcia (UWAGA: Tylko niektóre swoich elementów), niż korzystać z tej metody, jak tak:

@Override 
     public void onViewRecycled(MyViewHolder holder) { 
      super.onViewRecycled(holder); 

      // Set ImageView's Drawable as transperent 
      holder.myImageView.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), android.R.color.transparent)); 

      // Set background color as transperent 
      holder.bgContainer.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), android.R.color.transparent)); 

     } 

A teraz możesz zarządzać liczbą całkowitą ArrayList z identyfikacją/pozycją wybranych elementów (za pomocą metody onClick na elemencie widoku recyklera).

Za pomocą onBindViewHolder(MyViewHolder myViewHolder, int position) można normalnie wypełnić dane.A dla ustawienia tła możesz po prostu sprawdzić, czy id/pozycja jest w ArrayList, czy nie (Jeśli true, ustaw kolor tła na zielony inaczej zostaw to tak, jak jest, ponieważ będzie zarządzane przez metodę onViewRecylcer i nie wpłynie na inne przewijane przedmioty z zielonym tłem, nawet jeśli nie jest wybrane).

Mam nadzieję, że pomoże komuś i sprawi, że widok recylera z wyborem będzie nieco łatwiejszy.

Powiązane problemy