为什么在 RecyclerView.Adapter 的 onBindViewHolder 中添加 OnClickListener 被认为是不好的做法?

我有一个类的以下代码,它工作正常:RecyclerView.Adapter

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.Viewholder> {

    private List<Information> items;
    private int itemLayout;

    public MyAdapter(List<Information> items, int itemLayout){
        this.items = items;
        this.itemLayout = itemLayout;
    }

    @Override
    public Viewholder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(itemLayout, parent, false);
        return new Viewholder(v);
    }

    @Override
    public void onBindViewHolder(Viewholder holder, final int position) {
        Information item = items.get(position);
        holder.textView1.setText(item.Title);
        holder.textView2.setText(item.Date);

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(view.getContext(), "Recycle Click" + position, Toast.LENGTH_SHORT).show();
            }
        });

       holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
       @Override
       public boolean onLongClick(View v) {
          Toast.makeText(v.getContext(), "Recycle Click" + position, Toast.LENGTH_SHORT).show();
           return true;
       }
});
    }

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

    public class Viewholder extends RecyclerView.ViewHolder {
        public  TextView textView1;
        public TextView textView2;

        public Viewholder(View itemView) {
            super(itemView);
            textView1=(TextView) itemView.findViewById(R.id.text1);
            textView2 = (TextView) itemView.findViewById(R.id.date_row);

        }
    }
}

但是,我认为在方法中实现 OnClickListener 是一种不好的做法。为什么这是不好的做法,什么是更好的选择?onBindViewHolder


答案 1

最好在 ViewHolder 中处理单击逻辑的原因是因为它允许更显式的单击侦听器。正如Commonsware书中所表达的:

ListView 行中的可点击小部件(如 RatingBar)长期以来一直与行本身的点击事件发生冲突。获取可以单击的行,以及也可以单击的行内容,有时会变得有点棘手。使用RecyclizerView,您可以更明确地控制如何处理此类事情......因为您是设置所有点击式处理逻辑的人。

通过使用 ViewHolder 模型,与以前在 ListView 中相比,您可以在 RecyclerView 中为单击处理获得很多好处。我在一篇博客文章中写了这一点,比较了差异 - https://androidessence.com/recyclerview-vs-listview

至于为什么它在 ViewHolder 中而不是 在 中更好,那是因为为每个项目都调用了它,并且设置单击侦听器是一个不必要的选项,当您可以在 ViewHolder 构造函数中调用它一次时,可以重复一次。然后,如果您的单击响应取决于所单击项目的位置,则只需从 ViewHolder 内部调用即可。以下是我给出的另一个答案,它演示了如何在 ViewHolder 类中使用 from。onBindViewHolder()onBindViewHolder()getAdapterPosition()OnClickListener


答案 2

每次将视图与尚未看到的对象绑定时,都会调用该方法。每次你都会添加一个新的听众。onBindViewHolder

相反,你应该做的是,附加点击监听器onCreateViewHolder

例:

@Override
public Viewholder onCreateViewHolder(ViewGroup parent, int viewType) {
     View v = LayoutInflater.from(parent.getContext()).inflate(itemLayout, parent, false);
     final ViewHolder holder = new ViewHolder(v);

     holder.itemView.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
             Log.d(TAG, "position = " + holder.getAdapterPosition());
         }
     });
     return holder;
}

推荐