2014-11-12 19 views
19

Questo è il mio primo tentativo di implementare lo RecyclerView. Ho implementato un'interfaccia Callback tra Adapter e la classe ViewHolder per gestire gli eventi di clic sugli elementi dell'interfaccia utente (pulsanti). Sto riscontrando problemi nel trovare un riferimento allo ViewHolder in cui si è verificato il clic. Posso fare clic sullo Button per il primo elemento nell'elenco, tuttavia l'azione che ho definito viene eseguita sull'ultimo viewholder nella mia visualizzazione del riciclatore. Alla fine ho capito di passare la posizione attraverso la mia interfaccia, ma mi sto sforzando di capire come ottenere un riferimento a quello spettatore.Ottenere un riferimento a ViewHolder su RecyclerView Fare clic su

public class RoomAdapter extends RecyclerView.Adapter<RoomAdapter.RoomViewHolder> 
{ 
    List<Room> mRooms; 
    public RoomAdapter(List<Room> rooms) { 
     mRooms = rooms; 
    } 

    @Override 
    public RoomViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 
     final View viewItem = LayoutInflater 
       .from(viewGroup.getContext()) 
       .inflate(R.layout.room_rv_item,viewGroup,false); 
     return vh = new RoomViewHolder(viewItem,new IRoomViewClick() { 
      @Override 
      public void editname(int pos) { 

      } 
     }); 
    } 

    @Override 
    public void onBindViewHolder(RoomViewHolder roomViewHolder, int i) { 
     Room r = getItem(i); 
     roomViewHolder.label.setText(r.name); 


    } 
    public Room getItem(int position) 
    { 
     return mRooms.get(position); 
    } 
    @Override 
    public long getItemId(int position) { 
     return mRooms.get(position).getId(); 
    } 

    @Override 
    public int getItemCount() { 
     return mRooms.size(); 
    } 

    public static class RoomViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener 
    { 
     TextView label; 
     Button editBtn; 
     LinearLayout labelView; 
     Button saveBtn; 
     Button deleteBtn; 
     EditText editNameET; 
     IRoomViewClick mListener; 
     public RoomViewHolder(View itemView, IRoomViewClick listener) { 
      super(itemView); 
      labelView = (LinearLayout) itemView.findViewById(R.id.labelview); 
      mListener = listener; 
      editBtn =(Button) itemView.findViewById(R.id.editbtn); 
      editBtn.setOnClickListener(this); 
      label = (TextView) itemView.findViewById(R.id.room_listitem_label); 

     } 

     @Override 
     public void onClick(View view) { 
      int pos = getPosition(); 
      mListener.editname(pos); 



     } 
    } 
    public static interface IRoomViewClick 
    { 
     public void editname(int pos); 
    } 

} 

enter image description here

+0

Vorrei che non solo io ottenere un ref al pulsante al posto del ViewHolder stessa? – gsueagle2008

+0

heh ... non ho letto attentamente la domanda ... pensavo che avessi bisogno di una posizione (dato che non ho visto il corpo di getPosition() nel tuo codice) ... ma sì, puoi mettere lì ViewHolder invece ... ma poi non conoscerai la posizione, dal momento che ... beh, è ​​RecyclerView e view/viewholder può essere ... riciclato ... – Selvin

+0

Sì, ho perso l'implementazione della funzione getPosition() nel mio codice. Questo probabilmente non ha aiutato. Non sono ancora completamente chiaro sull'impostazione e sul recupero dei tag e sulla conversione in un ViewHolder che posso manipolare. – gsueagle2008

risposta

19

è possibile impostare un tag per l'editBtn in onBindViewHolder:

public RoomViewHolder(View itemView, IRoomViewClick listener) { 
     .... 
     editBtn =(Button) itemView.findViewById(R.id.editbtn); 
     //add tag for this view 
     editBtn.setTag(this); 
     .... 
    } 

e farlo in onClick

@Override 
    public void onClick(View view) { 
     //getTag 
     RoomViewHolder holder = (RoomViewHolder)(view.getTag()); 
     int pos = getPosition(); 
     mListener.editname(pos); 
    ... 
    } 
+11

Incredibile che Google non abbia pensato a un modo migliore di farlo - quasi l'anno è passato e non c'è modo migliore per ottenere ViewHolder tramite il vecchio metodo setTag (che faceva parte del modello non ufficiale del titolare della vista) ... – Nuwisam

+1

qui come si otterrà getPosition() ??? –

1

risultare che RecycleView salva la posizione della vista io n il params vista del layout, quindi se si desidera solo la posizione vista dal di ottenere il giusto articolo dalla lista è possibile utilizzare questo:

RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) v.getLayoutParams(); 
lp.getViewPosition(); 
+0

'getViewPosition' è deprecato, ora dovresti usare' getViewLayoutPosition' o 'getViewAdapterPosition', di solito il secondo. – user3175580

5
@Override 
public void onClick(View v) { 
    int pos = getAdapterPosition(); //getPosition() is deprecated 
    notifyItemChanged(pos); 
} 

notifyItemChanged consente di notificare al onBindViewHolder, allora si può fare qualcosa di simile questo

public void onBindViewHolder(RoomViewHolder roomViewHolder, int i) { 
    Room r = getItem(i); 
    roomViewHolder.label.setText(r.name); 
    if(i == pos){ // Do Something } 

} 

Ogni volta che si fa clic sulla voce, cambierà il valore pos' e innescare la // fare qualcosa

10

In realtà si può fare meglio di getTag chiamando getChildViewHolder(View child) sul RecyclerView:

@Override 
public void onClick(View v) { 
    MyHolder holder = (MyHolder) mRecyclerView.getChildViewHolder(v); 
    holder.textView.setText("Clicked!"); 
} 
+0

darà accesso a tutte le viste nell'elemento o solo all'oggetto cliccato?https://github.com/CymChad/BaseRecyclerViewAdapterHelper/issues/594 –

+0

Quando si fa clic sulla vista, questa funzione accederà a quella vista su cui si fa clic. Ma a parte il fatto che sia nel gestore di 'onClick', può ottenere viste cliccate o meno. –

+0

grazie, sto pensando di ottenere una mappa bitmap riciclabilità visualizzate le immagini visualizzate da condividere tramite whatsapp !! ottenere l'immagine da cache funziona bene ma è molto lenta (usando l'affresco) !! –

Problemi correlati