Cliquez sur l'article et sa position dans RecyclerView

je remplace mon ListView par RecyclerView , liste montrant ok, mais je voudrais savoir comment faire pour obtenir cliqué article et sa position, similaire à la méthode OnItemClickListener.onItemClick(AdapterView parent, View v, int position, long id) que nous utilisons dans ListView .

Merci pour les idées!

84
demandé sur Vasily Kabunov 2015-02-03 13:32:24

17 réponses

basé sur le lien: pourquoi RecyclerView n'a-t-il pas onItemClickListener()? en quoi RecyclerView diffère-t-elle de Listview? , et aussi l'idée générale de @Duncan, je donne ma solution ici:

  • définissez une interface RecyclerViewClickListener pour passer le message de l'adaptateur à Activity / Fragment :

    public interface RecyclerViewClickListener {
        public void recyclerViewListClicked(View v, int position);
    }
    
  • Dans Activity / Fragment mettre en œuvre le interface, et aussi passer l'écouteur à l'adaptateur:

    @Override
    public void recyclerViewListClicked(View v, int position){... ...}
    
    //set up adapter and pass clicked listener this
    myAdapter = new MyRecyclerViewAdapter(context, this);
    
  • Dans Adapter et ViewHolder :

    public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ItemViewHolder> {
       ... ... 
       private Context context;
       private static RecyclerViewClickListener itemListener;
    
    
       public MyRecyclerViewAdapter(Context context, RecyclerViewClickListener itemListener) {
           this.context = context;
           this.itemListener = itemListener;
           ... ...
       }
    
    
       //ViewHolder class implement OnClickListener, 
       //set clicklistener to itemView and, 
       //send message back to Activity/Fragment 
       public static class ItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
           ... ...
           public ItemViewHolder(View convertView) {
               super(convertView);
               ... ...
               convertView.setOnClickListener(this);
           }
    
           @Override
           public void onClick(View v) {
               itemListener.recyclerViewListClicked(v, this.getPosition());     
    
           }
       }
    }
    

après les tests, il fonctionne très bien.



[ mise à JOUR ]

depuis API 22, RecyclerView.ViewHoler.getPosition() est déprécié, donc à la place avec getLayoutPosition() .

139
répondu Xcihnegn 2018-05-10 17:24:48
public class MyRvAdapter extends RecyclerView.Adapter<MyRvAdapter.MyViewHolder>{
    public Context context;
    public ArrayList<RvDataItem> dataItems;

    ...
    constructor
    overrides
    ...

    class MyViewHolder extends RecyclerView.ViewHolder{
        public TextView textView;
        public Context context;

        public MyViewHolder(View itemView, Context context) {
            super(itemView);

            this.context = context;

            this.textView = (TextView)itemView.findViewById(R.id.textView);

            // on item click
            itemView.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v) {
                    // get position
                    int pos = getAdapterPosition();

                    // check if item still exists
                    if(pos != RecyclerView.NO_POSITION){
                        RvDataItem clickedDataItem = dataItems.get(pos);
                        Toast.makeText(v.getContext(), "You clicked " + clickedDataItem.getName(), Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
    }
}
24
répondu Uday Hiwarale 2016-09-26 16:19:59

voici un exemple pour définir un clic écouteur.

Adapter extends  RecyclerView.Adapter<MessageAdapter.MessageViewHolder> {  ...  }

 public static class MessageViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TextView     tv_msg;
        public TextView     tv_date;
        public TextView     tv_sendTime;
        public ImageView    sharedFile;
        public ProgressBar sendingProgressBar;

        public MessageViewHolder(View v) {
            super(v);
            tv_msg =  (TextView) v.findViewById(R.id.tv_msg);
            tv_date = (TextView)  v.findViewById(R.id.tv_date);
            tv_sendTime = (TextView)  v.findViewById(R.id.tv_sendTime);
            sendingProgressBar = (ProgressBar) v.findViewById(R.id.sendingProgressBar);
            sharedFile = (ImageView) v.findViewById(R.id.sharedFile);

            sharedFile.setOnClickListener(this);

        }

        @Override
        public void onClick(View view) {
        int position  =   getAdapterPosition();


            switch (view.getId()){
                case R.id.sharedFile:


                    Log.w("", "Selected"+position);


                    break;
            }
        }

    }
13
répondu Gilberto Ibarra 2015-07-29 22:19:04

mettez ce code où vous définissez la vue recycleur en activité.

    rv_list.addOnItemTouchListener(
            new RecyclerItemClickListener(activity, new RecyclerItemClickListener.OnItemClickListener() {
                @Override
                public void onItemClick(View v, int position) {

                    Toast.makeText(activity, "" + position, Toast.LENGTH_SHORT).show();
                }
            })
    );

alors faire une classe séparée et mettre ce code:

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {

    private OnItemClickListener mListener;
    public interface OnItemClickListener {
        public void onItemClick(View view, int position);
    }
    GestureDetector mGestureDetector;
    public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
        mListener = listener;
        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }
        });
    }
    @Override
    public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
        View childView = view.findChildViewUnder(e.getX(), e.getY());
        if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
            mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
        }
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
}
8
répondu bhumika rijiya 2018-03-09 04:42:16

si vous voulez l'événement de clic de recycle-View de l'activité/fragment au lieu de l'adaptateur, alors vous pouvez également utiliser la voie de raccourci suivante.

recyclerView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                final TextView txtStatusChange = (TextView)v.findViewById(R.id.txt_key_status);
                txtStatusChange.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Log.e(TAG, "hello text " + txtStatusChange.getText().toString() + " TAG " + txtStatusChange.getTag().toString());
                        Util.showToast(CampaignLiveActivity.this,"hello");
                    }
                });
                return false;
            }
        });

Vous pouvez également utiliser d'autres moyens comme l'utilisation de l'interface

5
répondu Amandeep Rohila 2015-08-20 12:01:59
recyclerViewObject.addOnItemTouchListener(
    new RecyclerItemClickListener(
        getContext(),
        recyclerViewObject,
        new RecyclerItemClickListener.OnItemClickListener() {
            @Override public void onItemClick(View view, int position) {
                // view is the clicked view (the one you wanted
                // position is its position in the adapter
            }
            @Override public void onLongItemClick(View view, int position) {
            }
        }
    )
);
4
répondu Cosmin Badulescu 2016-11-25 11:30:45

utiliser le code ci-dessous: -

public class SergejAdapter extends RecyclerView.Adapter<SergejAdapter.MyViewHolder>{

...

class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{


    @Override
    public void onClick(View v) {
        // here you use position
        int position = getAdapterPosition();
        ...

    }
}
}
2
répondu Akanksha Rathore 2016-07-06 11:33:59

RecyclerView ne fournit pas une telle méthode.

pour gérer les évènements clics sur RecyclerView, j'ai fini par implémenter onClickListener dans mon adaptateur, en liant le ViewHolder: dans mon ViewHolder je garde une référence à la vue racine (comme vous pouvez le faire avec vos ImageViews, TextViews, etc...) et lors de la fixation du viseur j'ai placé une étiquette sur elle avec des informations dont j'ai besoin pour gérer le clic (comme la position) et un clicklistener

1
répondu Zoubiock 2015-02-03 10:43:20
//Create below methods into the Activity which contains RecyclerView.


private void createRecyclerView() {

final RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recyclerView);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    MyAdapter myAdapter=new MyAdapter(dataAray,MianActivity.this);
    recyclerView.setAdapter(myAdapter);
    recyclerView.setItemAnimator(new DefaultItemAnimator());

    setRecyclerViewClickListner(recyclerView);
}

private void setRecyclerViewClickListner(RecyclerView recyclerView){

    final GestureDetector gestureDetector = new GestureDetector(MainActivity.this,new GestureDetector.SimpleOnGestureListener() {
        @Override public boolean onSingleTapUp(MotionEvent e) {
            return true;
        }
    });


    recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
        @Override
        public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
            View child =recyclerView.findChildViewUnder(motionEvent.getX(),motionEvent.getY());
            if(child!=null && gestureDetector.onTouchEvent(motionEvent)){
               int position=recyclerView.getChildLayoutPosition(child);
                String name=itemArray.get(position).name;

            return true;
        }

        @Override
        public void onTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {

        }

        @Override
        public void onRequestDisallowInterceptTouchEvent(boolean b) {

        }
    });
}
0
répondu Kamran 2015-08-16 07:55:46

d'Essayer cette façon

Classe Adaptateur:

 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);
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override public void onClick(View v) {
                listener.onItemClick(item);
            }
        });
    }
}

}

dans votre activité ou fragment :

ContentAdapter adapter = new ContentAdapter(itemList, this);

Note : implémenter L'OnItemClickListener basé sur le contexte donné par vous dans les méthodes activity ou fragment et overide.

0
répondu RajeshVijayakumar 2016-08-31 08:31:42

chaque fois que j'utilise une autre approche. Les gens semblent stocker ou obtenir position sur une vue, plutôt que de stocker une référence à un objet qui est affiché par le viseur.

j'utilise cette approche à la place, et je la stocke simplement dans ViewHolder quand onBindViewHolder() est appelé, et fixe la référence à null dans onViewRecycled().

chaque fois que le viseur devient invisible, il est recyclé. Donc cela n'affecte pas la consommation de mémoire.

@Override
public void onBindViewHolder(final ItemViewHolder holder, int position) {
    ...
    holder.displayedItem = adapterItemsList.get(i);
    ...
}

@Override
public void onViewRecycled(ItemViewHolder holder) {
    ...
    holder.displayedItem = null;
    ...
}

class ItemViewHolder extends RecyclerView.ViewHolder {
    ...
    MySuperItemObject displayedItem = null;
    ...
}
0
répondu Kirill Volkov 2017-10-19 22:34:21

courte extension pour Kotlin 151950920"
La méthode retourne la position absolue de tous les items (pas la position des seuls items visibles).

fun RecyclerView.getChildPositionAt(x: Float, y: Float): Int {
    return getChildAdapterPosition(findChildViewUnder(x, y))
}

et usage

val position = recyclerView.getChildPositionAt(event.x, event.y)
0
répondu comm1x 2018-07-04 23:16:46

Voici la façon la plus simple et la plus facile de trouver la position de l'article cliqué:

j'ai aussi fait face au même problème.

je voulais trouver la position de L'article cliqué/sélectionné du RecyclerView() et effectuer quelques opérations spécifiques sur cet article particulier.

méthode getAdapterPosition () fonctionne comme un charme pour ce genre de choses. J'ai trouvé cette méthode après une journée de longue recherche et après avoir essayé de nombreuses autres méthodes.

int position = getAdapterPosition();
Toast.makeText(this, "Position is: "+position, Toast.LENGTH_SHORT).show();

Vous n'avez pas à utiliser toute méthode supplémentaire. Il suffit de créer une variable globale nommée "position" et de l'initialiser avec getAdapterPosition() dans la méthode principale de l'adaptateur (classe ou similaire).

Voici une brève documentation de ce lien .

getAdapterPosition ajouté dans la version 22.1.0 int getAdapterPosition () Renvoie la position de L'Adaptateur de l'article représenté par ce visualiseur. Notez que ceci pourrait être différent de la position de getlayout() s'il y a des mises à jour d'adaptateur en attente mais qu'un nouveau passage de layout n'a pas encore eu lieu. RecyclerView ne gère aucune mise à jour d'adaptateur jusqu'à la prochaine mise en page transversale. Cela peut créer des incohérences temporaires entre ce que l'utilisateur voit sur l'écran et le contenu de l'adaptateur. Cette incohérence n'a pas d'importance puisqu'elle sera moins mais cela peut poser un problème si vous voulez utiliser la position du viseur pour accéder à l'adaptateur. Parfois, vous pouvez avoir besoin d'obtenir la position exacte de l'adaptateur pour faire certaines actions en réponse aux événements de l'utilisateur. Dans ce cas, vous devez utiliser cette méthode qui calculera la position de L'adaptateur du viseur.

heureux d'aider. N'hésitez pas à demander des doutes.

0
répondu Himanshu Nimje 2018-08-10 21:04:39

utilisez getLayoutPosition () dans votre méthode java d'interface personnalisée. Cela retournera la position choisie d'un élément, vérifier tous les détails sur

https://becody.com/get-clicked-item-and-its-position-in-recyclerview /

0
répondu Rana Aamer 2018-08-25 21:14:02

de la part du concepteur, vous pouvez définir la propriété onClick du listItem à une méthode définie avec un seul paramètre. J'ai un exemple de méthode défini ci-dessous. La méthode getAdapterPosition vous donnera l'index du listItem sélectionné.

public void exampleOnClickMethod(View view){
    myRecyclerView.getChildViewHolder(view).getAdapterPosition());
}

pour plus d'informations sur la mise en place D'un RecyclerView, voir la documentation ici: https://developer.android.com/guide/topics/ui/layout/recyclerview

0
répondu Spencer Milner 2018-09-19 05:03:50

il suffit d'ajouter un élément touch listener sur votre objet RecyclerView.

recyclerView.addOnItemTouchListener(  
new RecyclerItemClickListener(context, new RecyclerItemClickListener.OnItemClickListener() {
  @Override public void onItemClick(View view, int position) {
    // TODO Handle item click
  }
}));
0
répondu Maz_da 2018-09-28 12:22:02

dans onViewHolder set onClickListiner à toute vue et dans le clic latéral utiliser ce code:

Toast.makeText (Drawer_bar.cette "position" + position, du pain grillé.LENGTH_SHORT).show ();

remplacer Drawer_Bar par votre nom D'activité.

-3
répondu Thasreef Mogral 2018-05-02 11:36:51