web-dev-qa-db-fra.com

Définissez onItemClickListener dans onBindViewHolder () avec RecyclerView.Adapter

J'ai un objet personnalisé:

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

Ensuite, j'implémente RecyclerView.Adapter comme ceci:

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

Comme vous pouvez le voir dans onBindViewHolder(), j’ai défini onItemClickListener() pour son titulaire.

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

Mais je sais que la méthode onBindViewHolder() sera appelée à chaque fois qu’un nouvel élément apparaît dans la vue. Alors, cliquez sur écouteur dans onBindViewHolder() provoque des opérations coûteuses en son sein.

Comment puis-je résoudre ce problème? 

11
green.android

Vous devez définir sur onClickListener() dans la vue de la ViewHolder c'est-à-dire itemView dans votre cas. Il appellera la méthode onClick() dès que vous cliquerez sur la vue complète, à savoir la vue racine (itemView dans votre cas).

vous pouvez également définir onClickListener() sur les enfants de la racine, c'est-à-dire le nom et l'âge.

inside ViewHolder (View itemView) constructeur:

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

                }
            });

De même, vous pouvez également appeler onLongClickListner() également . Et name.setOnClickLisner() également dans la vue enfant.

8
Baqir

Vous pouvez implémenter onClickListener pour la vue parent comme ci-dessous:

//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

        }
    });

OU

si vous souhaitez définir onItemClickListener à partir de activity/fragmentrecyclerView est initialisé, vous pouvez suivre ce lien: http://www.littlerobots.nl/blog/Handle-Android-RecyclerView-Clicks/

2
himanshu1496

Vous pouvez définir l'événement Onclick pour des publics spécifiques:

Par exemple:

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

Le moyen le plus simple est de contenir une seule variable ItemClickListener dans votre adaptateur:

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

En activité:

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

remplacer ce 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;
                }
            });
        }
0
Karthik Kompelli