我想在我的活动/片段中存档
adapter.setOnItemClickListener { item ->
//do smt with item
}
我在适配器中设置但没有运气:
private var listener: OnItemClickListener?=null
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
val item = getItem(position)
item?.let { holder.bindView(it) }
holder.itemView.setOnClickListener { item?.let { listener?.onItemClick(it) } }
}
fun setOnItemClickListener(listener: (Item) -> Unit){
this.listener = listener as OnItemClickListener //this will throw type cast error
}
编辑1:我应该使用两种类型来完成同样的工作吗?
private var lambdaListener: ((Item) -> Unit)? = null
private var listener: OnItemClickListener?=null
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
val item = getItem(position)
item?.let { holder.bindView(it) }
holder.itemView.setOnClickListener {
item?.let { listener?.onItemClick(it) }
item?.let { it1 -> lambdaListener?.invoke(it1) }
}
}
fun setOnItemClickListener(listener: (Item) -> Unit) {
lambdaListener = listener
}
android-kotlin-extensions如何创建lambda表达式,如:view.setOnClickListener{view -> //do smt }
甚至
view.setOnClickListener{//do smt }
编辑决赛: 感谢标记正确的答案,它并没有真正解决问题,但给了我这个想法:
this.listener = object : OnItemClickListener {
override fun onItemClick(item: Item) = listener(item)
}
用OnItemClickListener仍然是一个kotlin接口,无需将其重写为java接口
答案 0 :(得分:4)
android-kotlin-extensions如何创建lambda表达式,如:
view.setOnClickListener{view -> //do smt }
甚至view.setOnClickListener{//do smt }
Kotlin有SAM Conversions。 view.setOnClickListener{//do smt }
有效,因为单参数方法有一个默认名称it
。
这意味着只要接口方法的参数类型与Kotlin函数的参数类型匹配,Kotlin函数文字就可以使用单个非默认方法自动转换为Java接口的实现。
当前仅Java接口支持SAM转换。有关进一步的讨论,请参阅here。
要解决这个问题,一种方法是自己包装lambda。
fun setOnItemClickListener(listener: (Item) -> Unit) {
listener = OnItemClickListener { listener.invoke(it) }
}
答案 1 :(得分:1)
您的lambda不适合强制转换为OnItemClickListener
界面。您必须手动实现接口并在那里调用该函数。要改进实施,您还可以使用inline
功能。
inline fun setOnItemClickListener(crossinline listener: (Item) -> Unit) {
this.listener = OnItemClickListener { listener(it) }
}
如果OnItemClickListener
是 Java 接口,这将有效。如果它是 Kotlin 接口,则必须使用object
表示法实现它。
inline fun setOnItemClickListener(crossinline listener: (Item) -> Unit) {
this.listener = object : OnItemClickListener {
override fun onItemClick(item: Item) = listener(item)
}
}