繁体   English   中英

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

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

我有一个自定义对象:

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;
  }
}

然后我像这样实现RecyclerView.Adapter

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);
  }
}

正如您在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();
      }
    });
  }

但我知道每次新项目滚动到视图时都会调用onBindViewHolder()方法。 因此,在onBindViewHolder()内部调用click监听器会导致其中的昂贵操作。

我该如何解决这个问题?

您需要在ViewHolder的视图上设置ViewHolder onClickListener() ,即在您的情况下为ViewHolder 单击完整视图即根视图(在您的情况下为onClick() ,它将调用onClick()方法

你也可以在root的子onClickListener()上设置onClickListener() ,即名称和年龄。

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

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

                }
            });

同样,您也可以调用onLongClickListner() 并且在子视图上也有name.setOnClickLisner()

您可以为父视图实现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

        }
    });

要么

如果你想从初始化了recyclerView activity/fragment设置onItemClickListener ,你可以点击这个链接: http//www.littlerobots.nl/blog/Handle-Android-RecyclerView-Clicks/

您可以为特定受众设置事件Onclick:

例如:

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

最简单的方法是在适配器中保存单个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);
    }
}

在活动中:

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

替换此代码,

        @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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM