Can we make use of in built setOnCliclListener on recycler view row item instead of custom item click listener?

Can we make use of in built setOnCliclListener on recycler view row item instead of custom item click listener?



I have seen many examples for providing click functionality (for selecting row item in recycler view) to a row item, but all of them are using custom click listener class to achieve this. Is there any method to achieve this click functionality?





There's no built in setOnItemClickListener for RecyclerView. Have a look here also: stackoverflow.com/questions/24885223/…
– Andy Res
Aug 15 at 22:28



setOnItemClickListener


RecyclerView





I checked that question and apparently every answer seems to be incorrect, including the accepted one. Wow!
– EpicPandaForce
Aug 15 at 23:27





2 Answers
2



Detecting click on a RecyclerView item is very easy. All you need to do is define an interface (if you're not using Kotlin, in which case you just pass in a lambda):


public class MyAdapter extends RecyclerView.Adapter<MyViewHolder>
private final Clicks clicks;

public MyAdapter(Clicks clicks)
this.clicks = clicks;


private List<MyObject> items = Collections.emptyList();

public void updateData(List<MyObject> items)
this.items = items;
notifyDataSetChanged(); // TODO: use ListAdapter for diffing instead if you need animations


public interface Clicks
void onItemSelected(MyObject myObject, int position);


public class MyViewHolder extends RecyclerView.ViewHolder
private MyObject myObject;

public MyViewHolder(View view)
super(view);
// bind views
view.setOnClickListener((v) ->
int adapterPosition = getAdapterPosition();
if(adapterPosition >= 0)
clicks.onItemSelected(myObject, adapterPosition);

);


public void bind(MyObject myObject)
this.myObject = myObject;
// bind data to views





Same code in Kotlin:


class MyAdapter(val itemClicks: (MyObject, Int) -> Unit): RecyclerView.Adapter<MyViewHolder>()
private var items: List<MyObject> = Collections.emptyList()

fun updateData(items: List<MyObject>)
this.items = items
notifyDataSetChanged() // TODO: use ListAdapter for diffing instead if you need animations


inner class MyViewHolder(val myView: View): RecyclerView.ViewHolder(myView)
private lateinit var myObject: MyObject

init
// binds views
myView.onClick
val adapterPosition = getAdapterPosition()
if(adapterPosition >= 0)
itemClicks.invoke(myObject, adapterPosition)




fun bind(myObject: MyObject)
this.myObject = myObject
// bind data to views





If you are using Kotlin then you can send method as constructor parameter or via setter method. You don't need to created any interface listener for this kind of situation in kotlin.


class ImageCategoryAdapter(val listener: (YourType) -> Unit) : RecyclerView.Adapter<ImageCategoryAdapter.ViewHolder>()

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder
return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_poll_category, parent, false))


override fun getItemCount() = yourList.size

override fun onBindViewHolder(holder: ViewHolder, position: Int)
// ...


inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
// ...
init
// this is the magic
itemView.setOnClickListener listener.invoke(yourList[adapterPosition])





In adapter we are taking function as constructor parameter named listener. and then on click of item view we are invoking that function with required type.


val adapter = ImageCategoryAdapter
// Your callback
// here it will be type of parameter which we are sending from adapter by invoking the function.
processClickedItem(it)



This is why i am getting addicted to kotlin. No interface callback needed for this kind of situation.



Updated
If you want to send the position also.


class ImageCategoryAdapter(val listener: (YourType, Int) -> Unit) : RecyclerView.Adapter<ImageCategoryAdapter.ViewHolder>()
...



You have to invoke this function with two parameter.


itemView.setOnClickListener listener.invoke(yourList[adapterPosition], adapterPosition)



Now as we can see there are multiple parameter so it will not work for parameter, we have to provide the variable name for this lambda function.


it


val adapter = ImageCategoryAdapter clickItem, position -> processClickedItem(clickItem, position)





Thankyou for all your help!
– sha
Aug 22 at 0:08






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)