首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么在OnClickListener的onBindViewHolder中添加RecyclerView.Adapter被认为是错误的做法?

为什么在OnClickListener的onBindViewHolder中添加RecyclerView.Adapter被认为是错误的做法?
EN

Stack Overflow用户
提问于 2015-11-21 16:35:52
回答 8查看 44.8K关注 0票数 83

我有一个RecyclerView.Adapter类的以下代码,它运行得很好:

代码语言:javascript
运行
复制
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是不好的做法。为什么这种做法不好,还有什么更好的选择呢?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2015-11-21 16:47:44

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

与RatingBar一样,ListView行中的可单击小部件与行上的单击事件一直存在冲突。获取可以单击的行,以及也可以单击的行内容,有时会变得有些棘手。使用RecyclerView,您可以更明确地控制这类事情的处理方式,…因为你是设置所有点击处理逻辑的人。

通过使用ViewHolder模型,您可以在RecyclerView中获得比以前在ListView中更多的单击处理优势。我在一篇比较不同之处的博客文章中提到了这一点-- https://androidessence.com/recyclerview-vs-listview

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

票数 73
EN

Stack Overflow用户

发布于 2016-02-05 17:06:03

每次将视图与对象绑定时都会调用onBindViewHolder方法,而对象还没有被看到。每次你都会添加一个新的侦听器。

相反,您应该做的是在onCreateViewHolder上附加单击侦听器

示例:

代码语言:javascript
运行
复制
@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;
}
票数 19
EN

Stack Overflow用户

发布于 2015-11-21 16:43:06

onCreateViewHolder()方法将在每个viewType需要ViewHolder的头几次调用。每次新项目滚动到视图或数据更改时,都会调用onBindViewHolder()方法。您希望避免在onBindViewHolder()中进行任何昂贵的操作,因为它可以减慢滚动速度。这在onCreateViewHolder()中不太重要。因此,通常更好的做法是在onCreateViewHolder()中创建类似onCreateViewHolder()的东西,这样每个ViewHolder对象只发生一次。您可以在侦听器中调用getLayoutPosition()以获取当前位置,而不是接受提供给onBindViewHolder()position参数。

票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33845846

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档