11

Używam RecyclerView z układem jednego wiersza z ImageView i TextView.Uzyskiwanie pozycji widoku naCreateViewHolder

Chcę zaimplementować OnClickListener dla widoku, a nie dla oddzielnych obiektów ViewHolder. Jak mogę uzyskać położenie widoku w adapterze?

W tej chwili usuwam komentarze dotyczące kliknięć, ale nie mogę wybrać klikniętego widoku. Dodałem TODO w odpowiedniej linii.

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

naprawdę powinieneś ustawić OnClickListener w ViewHolder (final Zobacz itemView) konstruktor, w tym przypadku ViewHolder powinny wdrożyć OnClickListener – pskink

Odpowiedz

31

Ty nie może użyć parametru onBindViewHolderposition w zwrotnego. Jeśli nowa pozycja zostanie dodana powyżej, RecyclerView nie będzie ponownie odnawiać pozycji, więc pozycja jestprzestarzała. Zamiast tego, RecyclerView zapewnia metodę getAdapterPosition w 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; 
} 

Dodałem position != RecyclerView.NO_POSITION czek bo gdy element jest usuwany, RecyclerView znikną z widoku tak może być nadal kliknięciu przez użytkownika, ale jego pozycja adapter zwróci NO_POSITION.

+2

Cokolwiek kliknę, otrzymuję pozycję -1 (RecyclerView.NO_POSITION), jaki będzie problem? – akki

-1

nadpisanie metody getItemViewType:

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

Teraz sytuacja jest dostępny na 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

Nie rób tego - spowoduje to, że adapter utworzy nowy widok dla każdego elementu na liście, a nie je zutylizuje, ponieważ będzie uważał, że wszystkie są różne. – starkej2

Powiązane problemy