RecyclerVIew OnItemClick返回-1

时间:2016-04-04 21:39:55

标签: android android-recyclerview onitemclicklistener recycler-adapter

我想为RecyclerView行中的视图设置点击处理程序。我想处理片段中的项目点击。我试图通过this tutorial对其进行编码。但是当我尝试识别单击了哪个视图时,它返回-1。

我的适配器中有一个接口。

   public interface OnItemClickListener {
        void onItemClick(View itemView, int position);
    }
    public void setOnItemClickListener(OnItemClickListener listener) {
        this.mOnItemClickListener = listener;
    }

然后在ViewHolder构造函数中我称之为:

itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mOnItemClickListener != null) {
                        mOnItemClickListener.onItemClick(v, getLayoutPosition());
                    }
                }
            });

最后这里是我从片段中设置监听器的部分:

mFollowingAdapter.setOnItemClickListener(new FollowingAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View itemView, int position) {
                    Log.d(Constants.TAG, itemView.getId() + " " + position);
            }
        });

完整的VIewHolder代码:

public class ViewHolder extends RecyclerView.ViewHolder {
        private ImageView request_author_profile;
        private TextView request_name;
        private ImageView request_accept;
        private ImageView request_decline;

        public ViewHolder(final View itemView) {
            super(itemView);
            request_author_profile = (ImageView) itemView.findViewById(R.id.profile_image);
            request_name = (TextView) itemView.findViewById(R.id.request_name);
            request_decline = (ImageView) itemView.findViewById(R.id.btn_request_decline);
            request_accept = (ImageView) itemView.findViewById(R.id.btn_request_accept);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mOnItemClickListener != null) {
                        mOnItemClickListener.onItemClick(itemView, getLayoutPosition());
                    }
                }
            });
        }
    }

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

尝试在onBindViewHolder()方法而不是ViewHolder构造函数中设置匿名中间侦听器,将项目在数据集中的位置传递给onItemClick()而不是getLayoutPosition()。< / p>

ViewHolder的目的是表示屏幕上可见的单个列表项,最初与任何底层数据无关。只要应显示该项,onBindBiewHolder()方法就会将其绑定到数据集中的项目。设置中间监听器将确保数据集中项目的位置将传递给客户端监听器。

这是一个简单的例子:

适配器:

public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
    public interface OnItemClickListener {
        void onItemClick(int position);
    }

    /* this is the public listener that you set from the outside of the adapter */
    private OnItemClickListener mOnItemClickListener;

    @Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {

        /* update the intermediate listener so that it passes
         * the correct position to the public listener */
        holder.setOnClickListener(new OnClickListener() {
            if (mOnItemClickListener != null) {
                mOnItemClickListener.onItemClick(position);
            }
        }
        /* ... */
    }
    /* ... */
}

ViewHolder:

public class MyViewHolder extends RecyclerView.ViewHolder {
    private View mView;

    public MyViewHolder(final View itemView) {
        mView = itemView;
    }

    /* delegate the setter to the (root) view */
    public setOnClickListener(OnClickListener listener) {
        mView.setOnClickListener(listener);
    }
}

请注意,这是一个非常好的实现性能,因为它每次绑定ViewHolder时都会创建一个新的侦听器对象,但我认为它很好地传达了这个想法。更好的解决方案是在ViewHolder中保留一个字段来描述数据集中的位置,在中间监听器中使用它并在onBindViewHolder()中更新它的值。