17

How is it possible to get the position of the item which was clicked in the RecyclerView row and than make a intent to an activity in the onClick method ? Here is my adapter:

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

    private LayoutInflater inflater;
    List<Information> data= Collections.emptyList();

    public SergejAdapter(Context context, List<Information> data){
      inflater = LayoutInflater.from(context);
        this.data=data;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = inflater.inflate(R.layout.navigation_drawer_custom_row,parent,false);
        MyViewHolder holder= new MyViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        Information current=data.get(position);
        holder.title.setText(current.title);
    }

    @Override
    public int getItemCount() {
        return data.size();
    }
    class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
        TextView title;
        ImageView icon;

        public MyViewHolder(View itemView){
            super(itemView);
            title= (TextView) itemView.findViewById(R.id.listText);
            icon = (ImageView) itemView.findViewById(R.id.listIcon);
            icon.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            Context context = itemView.getContext();
            Intent intent = new Intent(context, Ernaehrung.class);
            context.startActivity(intent);

        }
    }

Here I just have an onClick when one of the images was clicked, but every image has the same intent.

sfmirtalebi
  • 370
  • 7
  • 16
SerOsDeveloper
  • 253
  • 1
  • 3
  • 12
  • Check this post out: http://stackoverflow.com/questions/26830505/create-a-listview-with-selectable-rows-change-background-color-of-listview-rows. It incorporates some of these things into it – Alex K Jan 11 '15 at 22:49
  • 3
    getPosition() is deprecated. You have to use getLayoutPosition() or getAdapterPosition(). For reference https://developer.android.com/reference/android/support/v7/widget/RecyclerView.ViewHolder.html – Kavin Prabhu Apr 16 '15 at 09:50

3 Answers3

60

You can get postion from ViewHolder by using getAdapterPosition() method. Like in code below:

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();
            ...

        }
    }
}
Joaquin Iurchuk
  • 5,499
  • 2
  • 48
  • 64
Konrad Krakowiak
  • 12,285
  • 11
  • 58
  • 45
  • Thank you for the quick answer! I did it with the switch case, works fine. – SerOsDeveloper Jan 11 '15 at 12:26
  • Take into account that setting the position manually is redundant or more specific unnecessary work. – reVerse Jan 11 '15 at 12:55
  • 2
    This is wrong. First of all, ViewHolder already has a position so you don't need to add it. Secondly, the position the onBind may not match the position during the onClick (if items moved). Instead, use `ViewHolder#getPosition` to get the up to date position. – yigit Jan 11 '15 at 22:32
  • I can't removed my answer so I edited it to proper answer. My solution works to but this is to much better. Thanks – Konrad Krakowiak Jan 11 '15 at 22:57
  • 7
    `getPosition()` is now deprecated and replaced with `getAdapterPosition()` – dzikovskyy Jul 05 '15 at 13:20
  • 1
    `getAdapterPosition()` Working :) – Pratik Butani Aug 13 '15 at 09:57
  • @Konrad Krakowiak, Even in `onClick()` it will give perfect position? Even if `setTag()` and `getTag()` not used? – Jimit Patel Nov 28 '16 at 11:41
  • @JimitPatel you shouldn't user setTag() getTag() if you want to "cache" value in view holder just create member in viewholder and set value for this member – Konrad Krakowiak Nov 28 '16 at 12:30
1

Within your onClick(View v) you can simply call getLayoutPosition() which will return the position where the click happened. Check the official docs for further information.

So your code would be something like this:

@Override
public void onClick(View v) {
    switch(getLayoutPosition()){
       //TODO
    }
}

Preferably you should use an Interface to handle the click.

reVerse
  • 35,075
  • 22
  • 89
  • 84
  • `getPosition()` is deprecated. Use `getAdapterPosition()` instead. – Joaquin Iurchuk Jan 13 '16 at 15:18
  • 1
    @joaquin Instead of `getPosition()` we now have `getLayoutPosition()` and `getAdapterPosition()`. If you wanna have the same effect you should call `getLayoutPosition()` since it maps to the same method stub. `getAdapterPosition()` does something different. – reVerse Jan 13 '16 at 17:29
  • thanks for the data. I thought that getAdapterPosition() had the same effect. – Joaquin Iurchuk Jan 13 '16 at 17:40
  • 2
    @joaquin I'd say 99% of the time it will return the same value, but that's what the docs say to `getAdapterPosition()`: *Note that this might be different than the getLayoutPosition() if there are pending adapter updates but a new layout pass has not happened yet.* – reVerse Jan 13 '16 at 17:42
1

or you can just add :

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

...
    class MyViewHolder extends RecyclerView.ViewHolder {

        public MyViewHolder (View itemView) {
            super(itemView);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.d(TAG, "Element " + getAdapterPosition() + " clicked.");
                }
            });
        }


    }
Thiago
  • 12,778
  • 14
  • 93
  • 110