RecyclerView onItemClick Listener
Solution 1
first store whole view in your viewHolder:
public class FeedListRowHolder extends RecyclerView.ViewHolder {
protected TextView title;
protected View mRootView;
public FeedListRowHolder(View view) {
super(view);
this.title = (TextView) view.findViewById(R.id.title);
mRootView = view;
}
then set click listener at onBindViewHolder
:
@Override
public void onBindViewHolder(FeedListRowHolder feedListRowHolder, int i) {
FeedItem feedItem = feedItemList.get(i);
feedListRowHolder.title.setText(Html.fromHtml(feedItem.getTitle()));
feedListRowHolder.mRootView.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
}
});
}
Solution 2
I know its a little late but for all those who wander and are not lost. I found this elegant solution here.
So basically you create a ItemClickSupport class like below
public class ItemClickSupport {
private final RecyclerView mRecyclerView;
private OnItemClickListener mOnItemClickListener;
private OnItemLongClickListener mOnItemLongClickListener;
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mOnItemClickListener != null) {
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
mOnItemClickListener.onItemClicked(mRecyclerView, holder.getAdapterPosition(), v);
}
}
};
private View.OnLongClickListener mOnLongClickListener = new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (mOnItemLongClickListener != null) {
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
return mOnItemLongClickListener.onItemLongClicked(mRecyclerView, holder.getAdapterPosition(), v);
}
return false;
}
};
private RecyclerView.OnChildAttachStateChangeListener mAttachListener
= new RecyclerView.OnChildAttachStateChangeListener() {
@Override
public void onChildViewAttachedToWindow(View view) {
if (mOnItemClickListener != null) {
view.setOnClickListener(mOnClickListener);
}
if (mOnItemLongClickListener != null) {
view.setOnLongClickListener(mOnLongClickListener);
}
}
@Override
public void onChildViewDetachedFromWindow(View view) {
}
};
private ItemClickSupport(RecyclerView recyclerView) {
mRecyclerView = recyclerView;
mRecyclerView.setTag(R.id.item_click_support, this);
mRecyclerView.addOnChildAttachStateChangeListener(mAttachListener);
}
public static ItemClickSupport addTo(RecyclerView view) {
ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
if (support == null) {
support = new ItemClickSupport(view);
}
return support;
}
public static ItemClickSupport removeFrom(RecyclerView view) {
ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
if (support != null) {
support.detach(view);
}
return support;
}
public ItemClickSupport setOnItemClickListener(OnItemClickListener listener) {
mOnItemClickListener = listener;
return this;
}
public ItemClickSupport setOnItemLongClickListener(OnItemLongClickListener listener) {
mOnItemLongClickListener = listener;
return this;
}
private void detach(RecyclerView view) {
view.removeOnChildAttachStateChangeListener(mAttachListener);
view.setTag(R.id.item_click_support, null);
}
public interface OnItemClickListener {
void onItemClicked(RecyclerView recyclerView, int position, View v);
}
public interface OnItemLongClickListener {
boolean onItemLongClicked(RecyclerView recyclerView, int position, View v);
}
}
And then in your activity/fragment where you have defined and bind your recyclerView just do the following
//Here the mRecyclerView is the name of the defined recyclerView
ItemClickSupport.addTo(mRecyclerView).setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
@Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
// do it
}
});
Also, you need to create an ids.xml file inside your res/values folder and define the following inside
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="item_click_support" type="id" />
</resources>
I hope this helps. Still recommend you to go through the article to read more regarding it.
Solution 3
First you have to implement your own OnItemTouchListener :
static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener{
private GestureDetector gestureDetector;
public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener){
gestureDetector = new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onSingleTapUp(MotionEvent e) {
//here get the view that has been touched
View child = recyclerView.findChildViewUnder(e.getX(),e.getY());
//now pass the item and its position to your click listener
if(child!=null && clickListener!=null){
clickListener.onClick(child, recyclerView.getChildPosition(child));
}
return true;
}
@Override
public void onLongPress(MotionEvent e) {
}
});
}
public static interface ClickListener {
public void onClick(View view, int position);
}
@Override
public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
//use the gesture detector to intercept singletap and longtouch events
gestureDetector.onTouchEvent(motionEvent);
return false;
}
@Override
public void onTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
}
}
And then you will have to implement the ClickListener that will be called by the RecyclerTouchListener above :
private RecyclerTouchListener.ClickListener mClickListener = new RecyclerTouchListener.ClickListener() {
@Override
public void onClick(View view, final int position) {
//Do something with your item...
mRecyclerAdapter.getElementAt(position).doSomething();
}
}
Sun
Updated on June 09, 2022Comments
-
Sun almost 2 years
How to implement
RecyclerView
onItemClick listener as we do with ListView, this is my old Adapter class usingListView
:public class GenreAdapter extends BaseAdapter { .... @Override public View getView(final int position, View convertView, ViewGroup parent) { // convert view = design View v = convertView; if (v == null) { holder = new ViewHolder(); v = vi.inflate(Resource, null); holder.textTitle = (TextView) v.findViewById(R.id.textTitle); v.setTag(holder); } else { holder = (ViewHolder) v.getTag(); } holder.textTitle.setText(genreArrayList.get(position).getTitle()); v.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Bundle bundle = new Bundle(); bundle.putSerializable("data", genreArrayList); bundle.putInt("current", position); Intent intent = new Intent(context, MovieActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtras(bundle); context.startActivity(intent); } }); return v; } static class ViewHolder { public TextView textTitle; }
MainFragment.java:-
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { view = inflater.inflate(R.layout.fragment_main, container, false); /* Initialize recycler view */ mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view); mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST)); list = new ArrayList<MainPoho>(); adapter = new MainAdapter(getActivity(), list); mRecyclerView.setAdapter(adapter); ....... }
And here is my new
Adapter
class usingRecyclerView
:public class MyRecyclerAdapter extends RecyclerView.Adapter<FeedListRowHolder> { private List<FeedItem> feedItemList; private Context mContext; public MyRecyclerAdapter(Context context, List<FeedItem> feedItemList) { this.feedItemList = feedItemList; this.mContext = context; } @Override public FeedListRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_row, null); FeedListRowHolder mh = new FeedListRowHolder(v); return mh; } @Override public void onBindViewHolder(FeedListRowHolder feedListRowHolder, int i) { FeedItem feedItem = feedItemList.get(i); feedListRowHolder.title.setText(Html.fromHtml(feedItem.getTitle())); } @Override public int getItemCount() { if(feedItemList !=null){ return feedItemList.size(); } else { return 0; } }
public class FeedListRowHolder extends RecyclerView.ViewHolder { protected TextView title; public FeedListRowHolder(View view) { super(view); this.title = (TextView) view.findViewById(R.id.title); }
FeedItem.java:-
public class FeedItem { private String title; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }