首页 文章

在onCreateViewHolder中获取View的位置

提问于
浏览
14

我正在使用带有ImageView和TextView的单行布局的RecyclerView .

我想为View实现一个OnClickListener,而不是为单独的ViewHolder对象实现 . 如何在适配器中获取视图的位置?

现在我正在删除点击的评论,但我无法选择点击的视图 . 我在适当的行中添加了一个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);
        }
    }
}

3 回答

  • -1

    cannot 在回调中使用 onBindViewHolderposition 参数 . 如果上面添加了新项目,则RecyclerView will not 重新绑定您的项目,以便位置为 obsolete . 相反,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 .

  • 0

    您可以创建一种方法来更新 class 中的位置 .

    在我的情况下,我需要附加 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
     }
    
  • 40

    覆盖适配器中的getItemViewType方法:

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

    现在viewType是位置

    @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
           int position=viewType; //position 
            //your code 
    
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recursive, parent, false);
            return new ViewHolder(view);
        }
    

    例如

    public class BrandBtnAdapter extends RecyclerView.Adapter<BrandBtnAdapter.MyViewHolder>
    {
    
         //............
    
        @Override
        public int getItemViewType(int position)
        {
            //...
            return position;
        }
    
        @Override
        public BrandBtnAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
        {
            int position = viewType; //position 
    
            final View itemView = mInflater.inflate(mResource, parent, false);
            return new BrandBtnAdapter.MyViewHolder(itemView);
        }
    
    }
    

相关问题