web-dev-qa-db-fra.com

Comment rendre un RecyclerView non cliquable et transmettre un événement Click à la vue parent?

Est-il possible de rendre un RecyclerView non cliquable? Je le veux parce que mon RecyclerView montre juste quelques petites icônes, dans un cliquable CardView. Donc, si quelqu'un appuie sur les icônes, il doit simplement cliquer (et animer) le parent CardView à la place.

J'ai essayé ce qui suit:

  1. recyclerView.setClickable(false);
  2. recyclerView.setFocusable(false);
  3. Développez RecyclerView et faites onTouchEvent(MotionEvent) retourner false.
  4. Utilisez la méthode 3 ci-dessus et utilisez itemView.setClickable(false); dans l'adaptateur RecyclerView. Cela fonctionne, le clic est envoyé au parent. Cependant, maintenant le RecyclerView ne peut plus défiler.
  5. Définissez clickable="false", focusable="false", focusableInTouchMode="false" Dans l'élément de liste XML gonflé. (Voir commentaire @ Ibrahim)
  6. Appelez recyclerView#setLayoutFrozen(true) et itemView.setClickable(false);. Cela fonctionne, mais a le même problème que # 4.

Avez-vous des idées sur la façon de désactiver et de passer les événements de clic de RecyclerView à la vue parent? Notez que le RecyclerView doit toujours faire défiler (horizontal).


MODIFIER:
L'utilisateur @ c.dunlap a suggéré de définir les écouteurs OnClick sur les icônes et de simplement "rediriger" le clic vers l'action de clic du parent. Cela fonctionnerait, mais il n'y aura pas d'animation de clic sur la vue parent. Et si quelqu'un clique en dehors d'un itemView - mais toujours à l'intérieur du RecyclerView (par exemple le remplissage ItemDecoration) - le clic n'est pas détecté. Malheureusement, ce n'est pas une solution.

18
Thomas Vos

Vous devez étendre la vue parent et intercepter le clic, afin que la vue de recyclage ne la reçoive pas.

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    return true;
}

Crédits à: Solution

9
nsL

Ma façon préférée de gérer des choses comme celle-ci est d'attacher un écouteur de votre adaptateur qui sera appelé lorsque chaque icône dans votre vue de recycleur est cliquée. Ensuite, votre activité peut répondre de la manière appropriée. Par exemple:

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private MyAdapterListener mListener;

    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
         holder.itemView.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 mListener.iconClicked();
             }
         });
    }

    public void setListener(MyAdapterListener listener) {
        mListener = listener;
    }

    public interface MyAdapterListener {
        void iconClicked();
    }

}

Ensuite, dans votre activité, vous pouvez simplement créer une instance de MyAdapterListener et la définir comme écouteur pour l'adaptateur de votre vue Recycler. Ensuite, lorsque la fonction iconClicked() est déclenchée, exécutez le code qui serait exécuté lors du clic parent.

3
c.dunlap