Tengo un adaptador de vista de reciclador en Android. Parte de mi clase de adaptador se ve así:
private lateinit var itemLongClick: ItemLongClick override fun onCreateViewHolder(parent: ViewGroup, a: Int): RecyclerAdapter.ViewHolder { // Define And Initialize The Custom View And Its Holder// val myView = LayoutInflater.from(parent.context).inflate(customLayout, parent, false) val viewHolder = ViewHolder(myView) // What Happens When A List Item Is Long Clicked// myView.setOnLongClickListener { view -> // Differ Action To Class Instance// itemLongClick.longClicked(context, viewHolder.layoutPosition, view) // End Function// true } // Returns The Custom View// return viewHolder } fun setItemLongClick(itemLongClick: ItemLongClick) { // Sets The Value For this.itemLongClick// this.itemLongClick = itemLongClick }Creé una interfaz que se ve así:
interface ItemLongClick { // Function Declaration For When An Item Is Long Clicked// fun longClicked(context: Context, position: Int, view: View) }En lugar de escribir mi código de clic largo en la clase de adaptador, quiero diferenciarlo de la actividad que llama a la clase de adaptador. Sé que una forma de hacer esto es hacer una interfaz kotlin y luego llamarla en la otra clase como esta
userAdapter.setItemLongClick(object: ItemLongClick { override fun longClicked(context: Context, position: Int, view: View) { } })Pero esto parece desordenado. Sé que las interfaces de Java funcionan con SAM, pero tampoco quiero hacerlo. Lo que quiero es que onLongClick sea un Lambda, pero no estoy seguro de cómo configurar una expresión lambda de Kotlin para que esto funcione y no puedo encontrar un buen ejemplo en ninguna parte.
Gracias por adelantado
Tienes dos opciones:
1.) reemplazar la interfaz con typealias
typealias ItemLongClick = (Context, Int, View) -> Unit2.) agregue una función de extensión para configurar la interfaz como lambda en lugar de con un objeto anónimo
inline fun UserAdapter.setItemLongClick(crossinline longClick: (Context, Int, View) -> Unit) { setItemLongClick(object: ItemLongClick { override fun longClicked(context: Context, position: Int, view: View) { longClick(context, position, view) } }) }Ahora puedes llamar
userAdapter.setItemLongClick { context, position, view -> ... }Tenía un adaptador que necesito para cambiar los datos en función de un interruptor e hice algo como esto:
ListAdapter(private val context: Context, private val switchListener: (Boolean) -> Unit)Luego, donde enlacé el encabezado de mi lista seccionada, tenía:
private fun bindHeader(holder: HeaderViewHolder) { holder.switch.setOnCheckedChangeListener { _, isChecked -> callbackSwitchListener(isChecked) } }Y en mi fragmento:
private fun setupRecyclerView() { fabricationDataListAdapter = FabricationDataListAdapter(context!!) { isChecked: Boolean -> switchControl(isChecked) } val layoutManager = ListLayoutManager(context!!) this.recycler_view_all.layoutManager = layoutManager this.recycler_view_all.adapter = fabricationDataListAdapter }Donde el divertido switchControl cambió los datos en función del valor booleano.
No estoy seguro de si esto es lo que necesita, tengo un poco de prisa, pero esto se llama funciones de alto orden en kotlin, si no me equivoco.
Como señala la documentación de Kotlin para el lanzamiento de Kotlin 1.4:
Antes de Kotlin 1.4.0, podía aplicar conversiones SAM (Método abstracto único) solo cuando trabajaba con métodos Java e interfaces Java de Kotlin. A partir de ahora, también puede usar las conversiones SAM para las interfaces de Kotlin. Para hacerlo, marca una interfaz de Kotlin explícitamente como funcional con el modificador divertido.
fun interface Operation1 { operator fun invoke(x: String): String } fun interface Operation2 { fun doSomething(x: Int): String } val operation1 = Operation1 { "$it world!" } val operation2 = Operation2 { "$it world!" } fun main() { // Usage: First sample. println(operation1("Hello")) println(operation2.doSomething(0)) // Usage: Second sample. println(Operation1 { "$it world!" }("Hello")) println(Operation2 { "$it!" }.doSomething(0)) }Puede leer más sobre las interfaces funcionales aquí .