web-dev-qa-db-ja.com

onCreateViewHolderでのビューの位置の取得

私は、ImageViewとTextViewを持つ単一行レイアウトのRecyclerViewを使用しています。

個別のViewHolderオブジェクトではなく、ビューにOnClickListenerを実装したい。アダプターでビューの位置を取得するにはどうすればよいですか?

現在、クリックでコメントを削除していますが、クリックしたビューを選択できません。適切な行にTODOを追加しました。

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);
        }
    }
}
16
Thomas Mohr

あなたはできませんコールバックでpositiononBindViewHolderパラメータを使用します。上に新しいアイテムが追加された場合、RecyclerView されませんアイテムが再バインドされるため、位置は廃止になります。代わりに、RecyclerViewはViewHolderにgetAdapterPositionメソッドを提供します。

@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;
}

position != RecyclerView.NO_POSITIONチェックを追加しました。アイテムが削除されると、RecyclerViewはビューをフェードアウトし、ユーザーがクリックできるようにしますが、アダプターの位置はNO_POSITIONを返します。

45
yigit

クラスの位置を更新するメソッドを作成できます。

私の場合、watcherを添付し、arraylistを更新する位置を取得する必要があります。次に例を示します。

class DodolWatcher bla bla {
    private var position: Int = 0
    fun updatePosition(pos:Int)
    {
      position = pos
    }

    override fun onTextChanged(charSequence: CharSequence, i: Int, i2: Int, i3: Int) {
    Log.d("test", position.toString())
    }

}

onCreateViewHolderでは、ウォッチャーをedittextに接続できます

 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RVPaymentMethodAdapter.ViewHolder {
     ....
     bla bla
     ....
     theWatcher = DodolWatcher() <-- this is the trick
     amount.addTextChangedListener(theWatcher)
 }

次のようにbindViewHolderの位置を更新できます:

override fun onBindViewHolder(viewHolder: RVPaymentMethodAdapter.ViewHolder, position: Int) {
     theWatcher.updatePosition(viewHolder.adapterPosition)  <-- this is the trick
 }
0
Kakashi