paint-brush
Android RecyclerView onItemClickListener & getAdapterPosition(): A Better Wayby@rohitss
37,265 reads
37,265 reads

Android RecyclerView onItemClickListener & getAdapterPosition(): A Better Way

by Rohit SurwaseAugust 17th, 2018
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

I know you must have already found a way to get onItemClickListener() for your RecyclerView Adapter. But sometimes the way we think is not always the correct or a better way. Whenever anyone tries to find a way to getAdapterPosition() inside their Activity/Fragment/View. He or she comes across the well-known pattern of creating a custom interface with <strong><em>view</em></strong> and <strong><em>position</em></strong> as the parameters.

People Mentioned

Mention Thumbnail
Mention Thumbnail

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - Android RecyclerView onItemClickListener & getAdapterPosition(): A Better Way
Rohit Surwase HackerNoon profile picture

A lighter way to get that thing done smoothly.


**TL;DR**Instead of creating a custom ItemClickListener interface to getAdapterPosition() inside your Activity/Fragment/View and end up creating multiple Anonymous Classes under the hood for each item. Better pass the RecyclerView.ViewHolder using view.setTag() inside your ViewHolder and then getAdapterPosition() (…and many other things) from view.getTag() i.e. ViewHolder’s object inside your Activity/Fragment/View.

The Most Popular Way; The Problem

I know you must have already found a way to get onItemClickListener() for your RecyclerView Adapter. But sometimes the way we think is not always the correct or a better way. Whenever anyone tries to find a way to getAdapterPosition() inside their Activity/Fragment/View. He or she comes across the well-known pattern of creating a custom interface with view and position as the parameters.

public interface ItemClickListener {
    void onItemClick(View view, int position);
}

Later, we initialize the ItemClickListener instance using the public setter.

private ItemClickListener onItemClickListener;

...

public void setItemClickListener(ItemClickListener clickListener) {
    onItemClickListener = clickListener;
}

OR… by passing the ItemClickListener instance via constructor.

<a href="https://medium.com/media/d04f5e386b99fb58feae9904c6138ff4/href">https://medium.com/media/d04f5e386b99fb58feae9904c6138ff4/href</a>

And finally we pass our view and adapter position to the listener.

<a href="https://medium.com/media/5b7d4e262c63aa6326bc09761f67d7ec/href">https://medium.com/media/5b7d4e262c63aa6326bc09761f67d7ec/href</a>


And we know the rest of the part very well.Most of the articles out there depict the same thing. But there is a problem.

When we say itemView.setOnClickListener(new View.OnClickListener()…

It creates an Anonymous inner class under the hood which implements our ItemClickListener listener.

class AnonymousItemClickListener implements ItemClickListener{
    @Override
    public void onItemClick(View view, int position) {
        
    }
}

And we end up creating and initializing multiple Anonymous inner classes under the hood just for a click listener.

new AnonymousItemClickListener(){
        @Override
        public void onItemClick(View view, int position) {
            
        }
    };

I used to do the same. Because that is what we get to see all over the internet.

A Better Way; The Solution

But, recently I got a suggestion from a colleague to implement it in a better and lighter way. Let’s see how we can get adapter position, item id (…and many other things) inside our Activity/Fragment/View.

So, instead of creating new custom interface, we will use View.OnClickListener and initialize it in the way we used to do.

private View.OnClickListener onItemClickListener;

...

public void setItemClickListener(View.OnClickListener clickListener) {
    onItemClickListener = clickListener;
}

And we will pass the instance of ViewHolder via itemView to the listener using setTag().

private class MyViewHolder extends RecyclerView.ViewHolder {
    public MyViewHolder(View itemView) {
        super(itemView);
        itemView.setTag(this);
    }
}

In this way, we do not need to create Anonymous inner class as we can directly give the reference of onItemClickListener

private class MyViewHolder extends RecyclerView.ViewHolder {
    public MyViewHolder(View itemView) {
        super(itemView);
        itemView.setTag(this);
        itemView.setOnClickListener(onItemClickListener);
    }
}

Finally we can get adapter position and item id (…and many other things) inside our Activity/Fragment/View from the ViewHolder instance.

RecyclerView.ViewHolder viewHolder = (RecyclerView.ViewHolder) view.getTag();

int position = viewHolder.getAdapterPosition();
// viewHolder.getItemId();
// viewHolder.getItemViewType();
// viewHolder.itemView;


Simple! Isn’t it?Let me know your views and suggestions about this in the comment section.

Thanks for reading!


If you like the article, clap clap clap 👏👏👏 as many times as you can. It inspires me to come up with more beautiful articles.LIKED! Share on Facebook, LinkedIn, WhatsApp.


LIKED SO MUCH! Medium allows up to 50 claps.Also post a Tweet on Twitter.


About: Rohit Surwase,Techy by Birth. Writer by Hobby. Observer by Nature. Unpredictable by Character. Android Developer (Google Certified) by Profession.

Let’s be the friends on LinkedIn, Medium, Twitter and GitHub.