Skip to content

Instantly share code, notes, and snippets.

@riyazMuhammad
Last active December 30, 2020 15:10
Show Gist options
  • Star 67 You must be signed in to star a gist
  • Fork 20 You must be signed in to fork a gist
  • Save riyazMuhammad/1c7b1f9fa3065aa5a46f to your computer and use it in GitHub Desktop.
Save riyazMuhammad/1c7b1f9fa3065aa5a46f to your computer and use it in GitHub Desktop.
Easy Implementation of RecyclerView custom onItemClickListener

#The Problem In the way of replacing ListViews with RecyclerView I hit this obstacle where there is no onItemClickListener in RecyclerView ??? And when googled, I found almost all the posts saying we have to implement this using the GestureDetector. And some of them had used interfaces which is what I too thought of using in the first place. But even they were so much confusing and complex to understand.

#Solution

Prerequisites

  1. Interfaces (Donot worry if you never used one. But they are very simple concept) - CustomItemClickListener.java
  2. ViewHolder Adapter - ItemsListAdapter.java
  3. ViewHolder Item Class - ItemsListSingleItem.java
  4. The RecyclerView Itself - ItemsList (See Setting up the RecyclerView)

Solving the problem

Consider for example you have a list of thumbnails and a title to be listed. I would do the following to keep stuff simple and working. :)

Checkout the sample project here

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/items_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
public interface CustomItemClickListener {
public void onItemClick(View v, int position);
}
public class ItemsListAdapter extends RecyclerView.Adapter<ItemsListAdapter.ViewHolder> {
ArrayList<ItemListSingleItem> data;
Context mContext;
CustomItemClickListener listener;
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.items_list_single_item, parent, false);
final ViewHolder mViewHolder = new ViewHolder(mView);
mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.onItemClick(v, mViewHolder.getPosition());
}
});
return mViewHolder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.itemTitle.setText(Html.fromHtml(data.get(position).getTitle()));
if (!TextUtils.isEmpty(data.get(position).getThumbnailURL())) {
// I Love picasso library :) http://square.github.io/picasso/
Picasso.with(mContext).load(data.get(position).getThumbnailURL()).error(R.drawable.ic_no_image).
placeholder(R.drawable.ic_no_image).
transform(new RoundedCornersTransformation(5, 0)).
into(holder.thumbnailImage);
} else {
holder.thumbnailImage.setImageResource(R.drawable.ic_no_image);
}
}
@Override
public int getItemCount() {
return data.size();
}
public ItemsListAdapter(Context mContext, ArrayList<ItemsListSingleItem> data, CustomItemClickListener listener) {
this.data = data;
this.mContext = mContext;
this.listener = listener;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView itemTitle;
public ImageView thumbnailImage;
ViewHolder(View v) {
super(v);
itemTitle = (TextView) v
.findViewById(R.id.post_title);
thumbnailImage = (ImageView) v.findViewById(R.id.post_thumb_image);
}
}
}
public class ItemsListSingleItem {
private String title,thumbnailURL;
/**
* Just for the sake of internal reference so that we can identify the item.
*/
long id;
/**
*
* @param id
* @param title
* @param thumbnailURL
*/
public ItemsListSingleItem(long id, String title, String thumbnailURL) {
this.id = id;
this.title = title;
this.thumbnailURL = thumbnailURL;
}
public String getTitle() {
return title;
}
public long getID() {
return id;
}
public String getThumbnailURL() {
return thumbnailURL;
}
}
public class HomeActivity extends AppCompatActivity{
RecyclerView itemsList;
ItemsListAdapter adapter;
ArrayList<ItemsListSingleItem> data = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
itemsList = (RecyclerView) getView().findViewById(R.id.items_list);
itemsList.setHasFixedSize(true);
mLinearLayoutManager = new LinearLayoutManager(this);
itemsList.setLayoutManager(mLinearLayoutManager);
//let us add some items into the list
data.add(
new ItemsListSingleItem(
1,
"First Item",
"www.someUrlToMyThumbnailImage1"
));
data.add(
new ItemsListSingleItem(
2,
"Second Item",
"www.someUrlToMyThumbnailImage2"
));
adapter = new ItemsListAdapter(getActivity(), data, new CustomItemClickListener() {
@Override
public void onItemClick(View v, int position) {
Log.d(TAG, "clicked position:" + position);
long postId = data.get(position).getID();
// do what ever you want to do with it
}
});
itemsList.setAdapter(adapter);
}
}
@henguel19
Copy link

Thank you, your code help me so much

@PatelJay017
Copy link

Its Good, But i Want to Pass Array Adpter to Recyclerview Using Interface, So How Can I do?

@abdulbasit12345
Copy link

abdulbasit12345 commented Feb 6, 2018

i have a problem whit RoundedCornerTransformation()...what is this....onBindViewHolder() methods....

@AYLB
Copy link

AYLB commented Mar 7, 2018

Excellent, this solution is easy and help me so much :) thank you

@ganesha96
Copy link

Those Looking to add different button to different activities

    adapter = new CategoryAdapter(this, categoryList, new CustomItemClickListener() {
        @Override
        public void onItemClick(View v, int position) {
            long postId = categoryList.get(position).getID();
            if (postId == 1){
                Intent intent = new Intent(MainActivity.this, NewActivity.class);
                startActivity(intent);
            } else if (postId == 2){
                Intent intent1 = new Intent(MainActivity.this,  NewActivity1.class);
                startActivity(intent1);
            } else if (postId == 3){
                Intent intent2 = new Intent(MainActivity.this,  NewActivity2.class);
                startActivity(intent2);
            }
        }
    });
    recyclerView.setAdapter(adapter);

@porya74
Copy link

porya74 commented Feb 21, 2019

good solution, but I'm not sure about how the position gets where the CustomItemClickListener passed out as an argument in HomeActivity.(the code snippet below)
can anyone leave an explanation?

adapter = new ItemsListAdapter(getActivity(), data, new CustomItemClickListener() { @Override public void onItemClick(View v, int position) { Log.d(TAG, "clicked position:" + position); long postId = data.get(position).getID(); // do what ever you want to do with it } }); itemsList.setAdapter(adapter); }

@er361
Copy link

er361 commented Jun 11, 2019

thx help a lot
i am new in java so create iface and view on click it's kind of magical for me
but seems awesome!!!

@daniilkofficial
Copy link

Good idea!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment