RecyclerView is a great class that you should consider over ListView for building list interfaces. It offers more flexibility and has
built-in hooks that make implementing animations and custom layouts much easier compared to ListView.
Unfortunately RecyclerView is missing a couple
of features that ListView had built-in. For example the ability to add an OnItemClickListener that triggers when an item is clicked.
RecyclerView allows you to set an OnClickListener in your adapter, but passing on that click listener from your
calling code, to the adapter and to the ViewHolder, is complicated for catching a simple item click.
Fortunately, RecyclerView supplies a addOnItemTouchListener that will catch all touch events on the item View. You can hook up a GestureDetector to
figure out what happens and trigger an action from there. This has some problems as well. If you don’t implement this correctly, the GestureDetector
will steal touch events and will mess up things like ripples. Also, the target view is never actually receiving the touch events in that case so
your code has to emulate what happens when you click on a view to handle haptic feedback, sound effects and accessibility events.
I came up with a solution, which is to let the view which is the item in your RecyclerView, or more precisely, the ViewHolder.getItemView() handle the click.
The resulting code to hook up a click listener now looks like this:
Users of TwoWayView may notice how similar this is to ItemClickSupport in that library. Actually, I used TwoWayViews’ version in the Bundle app
before this, but encountered problems because it was using the touch listener technique. Once I implemented my own ItemClickSupport I went back to check the
internals of the version in TwoWayView and noticed that both implementations are pretty similar. I really like the elegant API that Lucas came up with
when implementing this in TwoWayView: no more passing around click listeners!
The main difference compared to the TwoWayView version is that my version uses a OnChildAttachStateChangeListener to set a OnClickListener
on the itemView of the ViewHolder without using a custom OnTouchListener.
Here’s the implementation:
You also need to define R.id.item_click_support using ids.xml
This code can be used freely, if you need to show your legal dept something, send them here.
I prefer setting a click listener using this method over passing around OnClickListeners and such. Of course it only covers the simple case where the whole
item needs to be clickable.
So next time you need your items to be clicked…consider this technique ;)