J'utilise l'adaptateur RecycleView
pour afficher des données dans une activité. Je souhaite implémenter onClickListener
dans l'activité. Je règle actuellement onClickListener
dans l'adaptateur comme d'habitude, ce qui fonctionne bien.
public void onBindViewHolder(MyHolder holder, final int position) {
final Listdata data = listdata.get(position);
holder.vname.setText(data.getName());
holder.vname.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(activity, "clicked on " +position, Toast.LENGTH_SHORT).show();
}
});
}
Cependant, je souhaite l'implémenter dans l'activité afin d'avoir un meilleur contrôle. Cela ne sert pas mon but. Je pense que ça va être utile pour beaucoup d'entre nous.
Vous devez vérifier ce didacticiel ici pour mieux comprendre comment vous pouvez obtenir le comportement que vous souhaitez.
Si vous manipulez la onClickListener
de votre activité, vous devez utiliser une implémentation de rappel avec une interface. Passez l'interface de l'activité à votre adaptateur, puis appelez la fonction de rappel de votre adaptateur lorsque vous cliquez sur certains éléments.
Voici un exemple d'implémentation du tutoriel.
Laissez-nous d'abord avoir l'interface.
public interface OnItemClickListener {
void onItemClick(ContentItem item);
}
Vous devez modifier votre adaptateur pour prendre l'auditeur comme paramètre comme celui indiqué ci-dessous.
private final List<ContentItem> items;
private final OnItemClickListener listener;
public ContentAdapter(List<ContentItem> items, OnItemClickListener listener) {
this.items = items;
this.listener = listener;
}
Maintenant, dans votre méthode onBindViewHolder
, définissez l'écouteur de clics.
@Override public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(items.get(position), listener);
}
public void bind(final ContentItem item, final OnItemClickListener listener) {
...
itemView.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
listener.onItemClick(item);
}
});
}
Définissez maintenant l'adaptateur dans votre RecyclerView
.
recycler.setAdapter(new ContentAdapter(items, new ContentAdapter.OnItemClickListener() {
@Override public void onItemClick(ContentItem item) {
Toast.makeText(getContext(), "Item Clicked", Toast.LENGTH_LONG).show();
}
}));
Donc tout le code de l'adaptateur ressemble à ce qui suit.
public class ContentAdapter extends RecyclerView.Adapter<ContentAdapter.ViewHolder> {
public interface OnItemClickListener {
void onItemClick(ContentItem item);
}
private final List<ContentItem> items;
private final OnItemClickListener listener;
public ContentAdapter(List<ContentItem> items, OnItemClickListener listener) {
this.items = items;
this.listener = listener;
}
@Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_item, parent, false);
return new ViewHolder(v);
}
@Override public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(items.get(position), listener);
}
@Override public int getItemCount() {
return items.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
private TextView name;
private ImageView image;
public ViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.name);
image = (ImageView) itemView.findViewById(R.id.image);
}
public void bind(final ContentItem item, final OnItemClickListener listener) {
name.setText(item.name);
Picasso.with(itemView.getContext()).load(item.imageUrl).into(image);
itemView.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
listener.onItemClick(item);
}
});
}
}
}
Si j'ai bien compris, vous voulez définir la logique de clic sur dans l'activité.
Vous pouvez le faire en définissant OnClickListener dans l'activité et en le transmettant au constructeur de l'adaptateur.
MyAdapter myAdapter = new MyAdapter(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(activity, "clicked on " +position, Toast.LENGTH_SHORT).show();
}
}));
Et votre constructeur MyAdapter serait:
final private OnClickListener onClickListener;
public MyAdapter(OnClickListener onClickListener) {
this.OnClickListener = OnClickListener;
}
Donc, votre nouveau code serait quelque chose comme ça
public void onBindViewHolder(MyHolder holder, final int position) {
final Listdata data = listdata.get(position);
holder.vname.setText(data.getName());
holder.vname.setOnClickListener(onClickListener);
}
Créer une interface pour la classe d'adaptateur
private OnItemClickListener mListener;
public CustomAdapter(List<Listdata> listdata, OnItemClickListener listener) {
mListener = listener;
...
...
}
private class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ViewHolder(View view) {
...
...
view.setOnClickLister(this);
}
@override
public void onClick(View v) {
mListener.onAdapterItemClick(getAdapterPosition())
}
}
interface OnItemClickListener {
void onAdapterItemClick(int position);
}
Laisser l'activité implémenter l'interface
public class CustomListActivity extends AppCompatActivity implements OnItemClickListener {
...
...
@override
public void onAdapterItemClick(int position) {
Toast.makeText(activity, "clicked on " +position, Toast.LENGTH_SHORT).show();
}
Il y a une autre façon de faire, consultez this implementation
Vous pouvez laisser votre Activity
implémenter View.OnClickListener
et le transmettre à l'adaptateur. Ci-dessous un exemple.
class RAdapter extends RecyclerView.Adapter<>{
View.OnClickListener listner;
public RAdapter(View.OnClickListener listner) {
this.listner = listner;
}
public void onBindViewHolder(MyHolder holder, final int position) {
holder.vname.setOnClickListener(listner);
}
}
Mais pour gérer le clic dans Activity
, vous aurez besoin d’une position cliquée. Vous pouvez l'avoir avec adapter.getAdapterPosition()
pour valider quel élément est cliqué.
En dehors de cela, si vous avez déjà une référence de Activity
, vous pouvez avoir OnClick
à l'intérieur de l'adaptateur et appeler une méthode publique de Activity
avec position pour effectuer une action.
Une meilleure façon de gérer les clics dans ViewHolder
. Voir l'exemple ci-dessous.
class Holder extends RecyclerView.ViewHolder implements View.OnClickListener {
Button button;
public Holder(View itemView) {
super(itemView);
button=itemView.findViewById(R.id.b1);
button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if(v.getId()==R.id.b1){
int position=getAdapterPosition();
// Call a public method of Activity here
// with postion
}
}
}
J'ai trouvé la méthode facile super duper! Je recommande celui-ci
Exemple de code:
public class ContentAdapter extends RecyclerView.Adapter<ContentAdapter.ViewHolder> {
public interface OnItemClickListener {
void onItemClick(ContentItem item);
}
private final List<ContentItem> items;
private final OnItemClickListener listener;
public ContentAdapter(List<ContentItem> items, OnItemClickListener listener) {
this.items = items;
this.listener = listener;
}
@Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_item, parent, false);
return new ViewHolder(v);
}
@Override public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(items.get(position), listener);
}
@Override public int getItemCount() {
return items.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
private TextView name;
private ImageView image;
public ViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.name);
image = (ImageView) itemView.findViewById(R.id.image);
}
public void bind(final ContentItem item, final OnItemClickListener listener) {
name.setText(item.name);
Picasso.with(itemView.getContext()).load(item.imageUrl).into(image);
itemView.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
listener.onItemClick(item);
}
});
}
}
}
Et utilisez l’adaptateur RecyclerView en utilisant le code ci-dessous:
recycler.setAdapter(new ContentAdapter(items, new ContentAdapter.OnItemClickListener() {
@Override public void onItemClick(ContentItem item) {
Toast.makeText(getContext(), "Item Clicked", Toast.LENGTH_LONG).show();
}
}));
j'ai trouvé cela de ici
J'espère que cela vous a aidé.