11

Sto utilizzando un RecyclerView con un layout a riga singola con un ImageView e un TextView.Ottenere la posizione di Visualizza in onCreateViewHolder

Desidero implementare un oggetto OnClickListener per la vista e non per gli oggetti ViewHolder separati. Come posso ottenere la posizione della vista nell'adattatore?

In questo momento sto eliminando i commenti sul clic, ma non riesco a selezionare la vista selezionata. Ho aggiunto un TODO nella riga appropriata.

public class CommentAdapter extends RecyclerView.Adapter<CommentAdapter.ViewHolder> { 

    /** List of Comment objects */ 
    private List<Comment> mCommentList; 

    /** Database with Comment objects */ 
    private CommentsDataSource mDataSource; 

    /** 
    * Construcutor for CommentAdapter 
    * 
    * @param commentList List of Comment objects 
    * @param dataSource Database with Comment objects 
    */ 
    public CommentAdapter(List<Comment> commentList, CommentsDataSource dataSource) { 
     this.mCommentList = commentList; 
     this.mDataSource = dataSource; 
    } 

    /** 
    * Add Comment objects to RecyclerView 
    * 
    * @param position The position where the Comment object is added 
    * @param comment Comment Object 
    */ 
    public void add(int position, Comment comment) { 
     mCommentList.add(position, comment); 
     notifyItemInserted(position); 
    } 

    /** 
    * Remove Comment objects from RecyclerView 
    * 
    * @param comment Comment Object 
    */ 
    public void remove(Comment comment) { 
     int position = mCommentList.indexOf(comment); 
     // Avoid double tap remove 
     if (position != -1) { 
      mCommentList.remove(position); 
      mDataSource.deleteComment(comment); 
      notifyItemRemoved(position); 
     } 
    } 

    @Override 
    public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) { 
     final View view = LayoutInflater.from(parent.getContext()) 
       .inflate(R.layout.single_line_row, parent, false); 
     view.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       // TODO get position 
       remove(mCommentList.get(getItemCount() - 1)); 
      } 
     }); 
     return new ViewHolder(view); 
    } 

    @Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
     final Comment comment = mCommentList.get(position); 
     holder.comment.setText(comment.getComment()); 
    } 

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

    public static class ViewHolder extends RecyclerView.ViewHolder { 

     /** ImageView icon */ 
     public ImageView icon; 

     /** TextView comment */ 
     public TextView comment; 

     /** 
     * Constructor for ViewHolder 
     * 
     * @param itemView Layout for each row of RecyclerView 
     */ 
     public ViewHolder(final View itemView) { 
      super(itemView); 
      icon = (ImageView) itemView.findViewById(R.id.icon); 
      comment = (TextView) itemView.findViewById(R.id.comment); 
     } 
    } 
} 
+0

si dovrebbe davvero impostare il vostro OnClickListener a ViewHolder costruttore (finali Visualizza itemView), in quel caso ViewHolder dovrebbe attuare OnClickListener – pskink

risposta

31

È non può utilizzare il parametro position di onBindViewHolder in un callback. Se si aggiunge un nuovo elemento sopra, RecyclerView non sarà rebind il tuo articolo quindi la posizione è obsoleto. Invece, RecyclerView fornisce un metodo getAdapterPosition sul ViewHolder.

@Override 
public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) { 
    final View view = LayoutInflater.from(parent.getContext()) 
      .inflate(R.layout.single_line_row, parent, false); 
    final ViewHolder holder = new ViewHolder(view); 
    view.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      final int position = holder.getAdapterPosition(); 
      if (position != RecyclerView.NO_POSITION) { 
       remove(mCommentList.get(position)); 
      } 
     } 
    }); 
    return holder; 
} 

Ho aggiunto position != RecyclerView.NO_POSITION controllo perché quando l'oggetto viene rimosso, RecyclerView svanirà la vista in modo che può ancora essere cliccato dall'utente ma la sua posizione adattatore tornerà NO_POSITION.

+2

Qualunque cosa clicchi, ottengo la posizione -1 (RecyclerView.NO_POSITION), quale sarà il problema? – akki

-1

di override metodo getItemViewType:

@Override 
public int getItemViewType(int position) { 
    //your code 
    return position; 
} 

Ora la posizione è accessibile viewType

@Override 
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     int position=viewType; 

     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recursive, parent, false); 
     return new ViewHolder(view); 
    } 
+5

Non farlo: farà in modo che l'adapter crei una nuova vista per ogni elemento del tuo elenco anziché riciclarli, poiché penserà che siano tutti tipi diversi. – starkej2