RecyclerVer elementoClickListener en Kotlin

Estoy escribiendo mi primera aplicación en Kotlin después de 3 años de experiencia con Android. Sólo confundido en cuanto a la forma de utilizar itemClickListener con un RecyclerView en Kotlin.

He intentado el acercamiento del rasgo,

public class MainActivity : ActionBarActivity() { protected override fun onCreate(savedInstanceState: Bundle?) { // set content view etc go above this line class itemClickListener : ItemClickListener { override fun onItemClick(view: View, position: Int) { Toast.makeText(this@MainActivity, "TEST: " + position, Toast.LENGTH_SHORT).show() } } val adapter = DrawerAdapter(itemClickListener()) mRecyclerView.setAdapter(adapter) } trait ItemClickListener { fun onItemClick(view: View, position: Int) } } 

Eso parecía muy redundante así que intenté el acercamiento de la clase interna:

 inner class ItemClickListener { fun onItemClick(view: View, position: Int) { startActivityFromFragmentForResult<SelectExerciseActivity>(SELECT_EXERCISES) } } 

Y luego simplemente configurar el oyente de clics del adaptador de esta manera:

 val adapter = WorkoutsAdapter(ItemClickListener()) 

Pero todavía no estoy satisfecho con esto porque creo que podría haber una manera mejor y más limpia. Estoy intentando lograr algo como esto: RecyclerView onClick

¿Alguna sugerencia?

Terminó con una variación de la respuesta aprobada

Definición de la función en la actividad:

 val itemOnClick: (View, Int, Int) -> Unit = { view, position, type -> Log.d(TAG, "test") } 

Se lo pasó al adaptador como este:

 class ExercisesAdapter(val itemClickListener: (View, Int, Int) -> Unit) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { // other stuff up here val vhExercise = ExerciseVH(view) // view holder // on to the view holder through the extension function vhExercise.onClick(itemClickListener) } } 

Función de extensión por Loop en la respuesta aprobada a continuación.

 fun <T : RecyclerView.ViewHolder> T.onClick(event: (view: View, position: Int, type: Int) -> Unit): T { itemView.setOnClickListener { event.invoke(it, getAdapterPosition(), getItemViewType()) } return this } 

4 Solutions collect form web for “RecyclerVer elementoClickListener en Kotlin”

Tengo un enfoque un poco diferente. Puede crear una extensión para su ViewHolder

 fun <T : RecyclerView.ViewHolder> T.listen(event: (position: Int, type: Int) -> Unit): T { itemView.setOnClickListener { event.invoke(getAdapterPosition(), getItemViewType()) } return this } 

A continuación, utilícelo en un adaptador como este

 class MyAdapter : RecyclerView.Adapter<MyAdapter.MyViewHolder>() { val items: MutableList<String> = arrayListOf() override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): MyViewHolder? { val inflater = LayoutInflater.from(parent!!.getContext()) val view = inflater.inflate(R.layout.item_view, parent, false) return MyViewHolder(view).listen { pos, type -> val item = items.get(pos) //TODO do other stuff here } } override fun onBindViewHolder(holder: MyViewHolder?, position: Int) { } override fun getItemCount(): Int { return items.size() } class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) { } } 

Estoy trabajando con mis colegas en la biblioteca que proporciona tales extensiones.

Usted podría intentar algo como:

 public class MainActivity : ActionBarActivity() { protected override fun onCreate(savedInstanceState: Bundle?) { [...] val adapter = DrawAdapter(::onItemClick) [...] } } fun onItemClick(view: View, position: Int) { //Do work } 

Y la conversión SAM sólo funciona como en Java 8, por lo que sólo tiene que utilizar un lambda:

 public class MainActivity : ActionBarActivity() { protected override fun onCreate(savedInstanceState: Bundle?) { [...] val adapter = DrawAdapter({view, position -> /*Do work*/ }) [...] } } 

En caso de que alguien está buscando una respuesta más sin lujos , he intentado lo siguiente – que es muy similar a la solución de AfzalivE :

En mi clase de adaptador pasé el clickListener como un parámetro. En onBindViewHolder , he utilizado setOnClickListener para llamar a clickListener y manejar el evento de clic.

MyAdapter.kt :

 class MyAdapter constructor(objects: ArrayList<MyObject>, val clickListener: (MyObject) -> Unit) : RecyclerView.Adapter<MyAdapter.Holder>() { private var mObjects : ArrayList<MyObject> = ArrayList<MyObject>() init { mObjects = objects } override fun onBindViewHolder(holder: Holder?, position: Int) { var item : MyObject = objects[position] // Calling the clickListener sent by the constructor holder?.containerView?.setOnClickListener { clickListener(item) } } // More code (ViewHolder definitions and stuff)... } 

Nota : Necesitaba una referencia del contenedor de mi elemento de lista (la vista raíz), que en este caso es containerView

Luego pasé mi objeto como parámetro sin necesidad de buscarlo en una lista de nuevo y manejarlo directamente en mi clase de Activity , en el momento en que configuro el adaptador:

MyActivity.kt :

 myRecyclerView?.adapter = MyAdapter(mObjects) { Log.e("Activity", "Clicked on item ${it.itemName}") } 

En RecyclerView puede poner clic en la vista inflada dentro de la clase del visor y llamarla desde el método de devolución de llamada onBindViewHolder, por ejemplo:

  class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { val view = view val tv_message = view.tv_message val tv_address = view.tv_address fun bind(listViewItem: ListViewItem) { view.setOnClickListener(View.OnClickListener { Toast.makeText(view.context,"Name :::: "+ listViewItem.name +" /n Address :::"+ listViewItem.address, Toast.LENGTH_LONG).show() }) } } 

Puede llamar desde el método onBindViewHolder del adaptador … por ejemplo:

  override fun onBindViewHolder(holder: ViewHolder, position: Int) { val listViewItem: ListViewItem = mListViewItems[position] holder.tv_message.text = listViewItem.name holder.tv_address.text = listViewItem.address holder.bind( mListViewItems[position]); } 
  • Android - Cómo detener la recarga de imágenes en Recyclerview al desplazarse
  • RecylcerView se desplaza a la parte superior del elemento eliminado
  • Los divisores no se mostraron en RecyclerView después de addItemDecoration () llamado
  • ¿Cómo saber si un RecyclerView / LinearLayoutManager se desplaza hacia arriba o abajo?
  • Android recyclerView findViewHolderForAdapterPosition devuelve null
  • RecyclerView? Android: attr / selectableItemBackground no funciona en los elementos
  • ¿Cómo realizar un seguimiento de los elementos seleccionados en un RecyclerView en Android?
  • RecyclerView muestra los datos eliminados en la lista
  • Hacer que ItemDecoration se mueva con Animation
  • Desplazamiento Horizontal Liso de Recyclerview dentro de Scrollview
  • ¿Cómo configurar la altura de recyclerview de forma programática?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.