简体   繁体   English

使用RecyclerView.Adapter在onBindViewHolder()内设置onItemClickListener

[英]Set onItemClickListener inside onBindViewHolder() with RecyclerView.Adapter

I have a custom object : 我有一个自定义对象:

Student.class Student.class

public class Student {
  private String name;
  private String age;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getAge() {
    return age;
  }

  public void setAge(String age) {
    this.age = age;
  }
}

Then I implement RecyclerView.Adapter like this : 然后我像这样实现RecyclerView.Adapter

MyAdapter.class MyAdapter.class

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

  private Context context;
  private ArrayList<Student> students = new ArrayList<>();

  public MyAdapter(Context mContext, ArrayList<Student> mStudents) {
    this.context = mContext;
    this.students = mStudents;
  }

  @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(context).inflate(R.layout.item_row, parent, false);
    return new ViewHolder(v);
  }

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

    final Student student = students.get(position);

    holder.name.setText(student.getName());
    holder.age.setText(student.getAge());

    holder.setClickListener(new ItemClickListener() {
      @Override public void onClickItem(int pos) {
        Toast.makeText(context, "CLICK : " + student.getName(), Toast.LENGTH_SHORT).show();
      }

      @Override public void onLongClickItem(int pos) {
        Toast.makeText(context, "LONG CLICK : " + student.getName(), Toast.LENGTH_SHORT).show();
      }
    });
  }

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

  public static class ViewHolder extends RecyclerView.ViewHolder
      implements View.OnClickListener, View.OnLongClickListener {

    private TextView name;
    private TextView age;
    private ItemClickListener mListener;

    public ViewHolder(View itemView) {

      super(itemView);
      name = (TextView) itemView.findViewById(R.id.tv_name);
      age = (TextView) itemView.findViewById(R.id.tv_age);

      itemView.setOnClickListener(this);
      itemView.setOnLongClickListener(this);
    }

    public void setClickListener(ItemClickListener listener) {
      this.mListener = listener;
    }

    @Override public void onClick(View view) {
      mListener.onClickItem(getLayoutPosition());
    }

    @Override public boolean onLongClick(View view) {
      mListener.onLongClickItem(getLayoutPosition());
      return true;
    }
  }

  public interface ItemClickListener {
    void onClickItem(int pos);

    void onLongClickItem(int pos);
  }
}

As you can see in onBindViewHolder() , I set onItemClickListener() for holder. 正如您在onBindViewHolder()看到的,我为holder设置onItemClickListener()

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

    final Student student = students.get(position);
    holder.name.setText(student.getName());
    holder.age.setText(student.getAge());

    holder.setClickListener(new ItemClickListener() {
      @Override public void onClickItem(int pos) {
        Toast.makeText(context, "CLICK : " + student.getName(), Toast.LENGTH_SHORT).show();
      }

      @Override public void onLongClickItem(int pos) {
        Toast.makeText(context, "LONG CLICK : " + student.getName(), Toast.LENGTH_SHORT).show();
      }
    });
  }

But I know onBindViewHolder() method will be called every time a new item scrolls into view. 但我知道每次新项目滚动到视图时都会调用onBindViewHolder()方法。 So call click listener inside onBindViewHolder() causes expensive operations inside it. 因此,在onBindViewHolder()内部调用click监听器会导致其中的昂贵操作。

How can I resolve this problem? 我该如何解决这个问题?

You need to set on onClickListener() on the view of the ViewHolder ie itemView in your case. 您需要在ViewHolder的视图上设置ViewHolder onClickListener() ,即在您的情况下为ViewHolder It will call the onClick() method as soon as you click the complete view ie root view (itemView in your case) 单击完整视图即根视图(在您的情况下为onClick() ,它将调用onClick()方法

you can also set onClickListener() on the children of the root ie name and age. 你也可以在root的子onClickListener()上设置onClickListener() ,即名称和年龄。

inside ViewHolder(View itemView) constructor: 在ViewHolder(View itemView)构造函数中:

itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(mContext,"clicked="+ getPosition(),Toast.LENGTH_SHORT).show();         

                }
            });

Similarly you can call onLongClickListner() also. 同样,您也可以调用onLongClickListner() And name.setOnClickLisner() on child view too. 并且在子视图上也有name.setOnClickLisner()

You can implement onClickListener for the parent view like below: 您可以为父视图实现onClickListener ,如下所示:

//holder.view - parent layout inside recyclerView item
holder.view.setTag(position);
holder.view..setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int pos = (int) v.getTag();
            Student student = students.get(pos);
            // Do your operation

        }
    });

OR 要么

if you want to set onItemClickListener from activity/fragment where recyclerView is initialised, you can follow this link: http://www.littlerobots.nl/blog/Handle-Android-RecyclerView-Clicks/ 如果你想从初始化了recyclerView activity/fragment设置onItemClickListener ,你可以点击这个链接: http//www.littlerobots.nl/blog/Handle-Android-RecyclerView-Clicks/

You can set event Onclick for specific audiences: 您可以为特定受众设置事件Onclick:

Eg: 例如:

 holder.layout.setClickListener(new ItemClickListener() {
  @Override public void onClickItem(int pos) {
    Toast.makeText(context, "CLICK : " + student.getName(), Toast.LENGTH_SHORT).show();
  }

Simplest way is holding single ItemClickListener inside your Adapter: 最简单的方法是在适配器中保存单个ItemClickListener

public class WalletListRecyclerAdapter extends RecyclerView.Adapter<WalletListRecyclerAdapter.ViewHolder> {
    private List<Wallet> wallets;
    private ItemClickListener itemClickListener;

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Wallet wallet = wallets.get(position);

        holder.root.setOnClickListener(v -> {
            if (itemClickListener != null)
                itemClickListener.onClick(holder.root, wallet);
        });
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        View root;

        public ViewHolder(View v) {
            super(v);
            root = v;
        }
    }


    public void setItemClickListener(ItemClickListener itemClickListener) {
        this.itemClickListener = itemClickListener;
    }

    public interface ItemClickListener {
        void onClick(View view, Wallet wallet);
    }
}

In Activity: 在活动中:

walletsAdapter = new WalletListRecyclerAdapter();
walletsAdapter.setItemClickListener((view, wallet) -> {
    Intent intent = new Intent(this, WalletActivity.class);
    intent.putExtra(Const.KEY_WALLET, wallet);
    startActivity(intent);
});

replace this code, 替换此代码,

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

            final Student student = students.get(position);
            holder.name.setText(student.getName());
            holder.age.setText(student.getAge());


            holder.v.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(context, "CLICK : " + student.getName(), Toast.LENGTH_SHORT).show();
                }
            });

            holder.v.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    Toast.makeText(context, "CLICK : " + student.getName(), Toast.LENGTH_SHORT).show();
                    return false;
                }
            });
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从 RecyclerViewAdapter 启动BottomSheet,它在onBindViewHolder 内扩展了RecyclerView.Adapter - Launching BottomSheet from a RecyclerViewAdapter that extends with RecyclerView.Adapter inside onBindViewHolder RecyclerView.Adapter onBindViewHolder()获取错误的位置 - RecyclerView.Adapter onBindViewHolder() gets wrong position 为什么在 RecyclerView.Adapter 的 onBindViewHolder 中添加 OnClickListener 被认为是不好的做法? - Why is adding an OnClickListener inside onBindViewHolder of a RecyclerView.Adapter considered bad practice? 在什么情况下不调用RecyclerView.Adapter中的onBindViewHolder()? - What are the circumstances under which onBindViewHolder() in RecyclerView.Adapter is not called? RecyclerView.Adapter 没有看到重写的 onBindViewHolder 方法? - RecyclerView.Adapter does not see overridden onBindViewHolder method? 如何从RecyclerView.Adapter的OnBindViewHolder中的另一个列表中提取列表 - how to extract a list from another list in OnBindViewHolder in RecyclerView.Adapter 最后 position 未调用 RecyclerView.Adapter 的 onBindViewHolder() - RecyclerView.Adapter's onBindViewHolder() is not called for last position 无法在我的类中使用 onBindViewHolder 实现 extends RecyclerView.Adapter - cannot implements with the onBindViewHolder in my class extends RecyclerView.Adapter 在 RecyclerView.Adapter 中,notifyItemChanged 并不总是调用 onBindViewHolder - In RecyclerView.Adapter, notifyItemChanged doesn't always call onBindViewHolder RecyclerView.Adapter更改onBindViewHolder中的主视图参考 - RecyclerView.Adapter change main view reference in onBindViewHolder
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM