在 Kotlin 中设置匿名接口
Setting anonymous interface in Kotlin
我的 Adapter
class:
中有一个接口
interface OnItemClickListener {
fun onItemClick(view: View)
}
请注意,我的 interface
使用 Kotlin。
我想通过这个方法设置:
public fun setItemClickListener(itemClickListener: OnItemClickListener) {
this.onItemClickListener = itemClickListener
}
如何在 Fragment
class 中使用 setItemClickListener
方法,就像我在 Java 中所做的那样?即
adapter.setItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(View view) {
// do something
}
}
我知道我可以使用 onItemTouchListener
,但我对 Kotlin 还是个新手,我正在尝试学习一些技术,例如 Lambdas
等。
这就是我们在 lambda 中的做法
adapter.setItemClickListener{ Log.i("Adapter", "onItemClick event fired on " + it.id) }
这里it
是View
的实例,是onItemClick
方法的参数
有关 it
的更多信息在此处 https://kotlinlang.org/docs/reference/lambdas.html#it-implicit-name-of-a-single-parameter
您可以在此处的 Kotlin 文档中找到更多信息 https://kotlinlang.org/docs/reference/lambdas.html#lambda-expressions-and-anonymous-functions
如果没有 lambda,你可以这样做
adapter.setItemClickListener(object :View.OnItemClickListener{
override fun onItemClick(p0: View?) {
}
})
如果你想用单一方法分配接口,你可以这样写:
adapter.setItemClickListener { view ->
/* some code here */
}
甚至更好:
adapter.setItemClickListener {
/* some code here, to use "view" use keyword "it" */
}
如果您想更深入地了解,让我们分析一下您的方法的签名:
public fun setItemClickListener(itemClickListener: OnItemClickListener)
这实际上等于
public fun setItemClickListener(singleMethodListener: (View) -> Unit)
如果你的最后一个参数是函数,你可以忘记'()',并传递lambda。
再举一个例子:
public fun setItemClickListener(parameter: Int, singleMethodListener: (View) -> Unit)
要调用上面的方法,您的代码应该是:
item.setItemClickListener(0) { /* lambda here */ }
问题是当你有不止一种方法的接口时,因为那样你就不能传递 lambda :(
示例:
interface OnItemClickListener {
fun onItemClick(view: View)
fun onDoubleItemClick(view: View)
}
那么,你不能通过sample labda,因为你必须定义2个方法。然后,你必须像 java 一样做同样的事情,但在其他语法中:
adapter.setItemClickListener(object : OnItemClickListener {
/* method declarations here, like in java */
})
我希望我已经解释了 Kotlin 中的 base-lambda 语法 :D 有任何问题吗?问 ;)
问题是您的界面是在 Kotlin 中定义的(因为它具有 fun
)。 Lambdas can only be used for Java interfaces:
Also note that this feature works only for Java interop; since Kotlin has proper function types, automatic conversion of functions into implementations of Kotlin interfaces is unnecessary and therefore unsupported.
所以在 Kotlin 中你应该使用
public fun setItemClickListener(itemClickListener: (View) -> Unit)
而不是定义 OnItemClickListener
。您还可以创建一个工厂方法:
// in Adapter's companion object
public inline fun OnItemClickListener(body: (View) -> Unit) = object : OnItemClickListener {
override fun onItemClick(view: View) { body(view) }
}
然后
adapter.setItemClickListener(Adapter.OnItemClickListener { view -> ... })
我的 Adapter
class:
interface OnItemClickListener {
fun onItemClick(view: View)
}
请注意,我的 interface
使用 Kotlin。
我想通过这个方法设置:
public fun setItemClickListener(itemClickListener: OnItemClickListener) {
this.onItemClickListener = itemClickListener
}
如何在 Fragment
class 中使用 setItemClickListener
方法,就像我在 Java 中所做的那样?即
adapter.setItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(View view) {
// do something
}
}
我知道我可以使用 onItemTouchListener
,但我对 Kotlin 还是个新手,我正在尝试学习一些技术,例如 Lambdas
等。
这就是我们在 lambda 中的做法
adapter.setItemClickListener{ Log.i("Adapter", "onItemClick event fired on " + it.id) }
这里it
是View
的实例,是onItemClick
方法的参数
有关 it
的更多信息在此处 https://kotlinlang.org/docs/reference/lambdas.html#it-implicit-name-of-a-single-parameter
您可以在此处的 Kotlin 文档中找到更多信息 https://kotlinlang.org/docs/reference/lambdas.html#lambda-expressions-and-anonymous-functions
如果没有 lambda,你可以这样做
adapter.setItemClickListener(object :View.OnItemClickListener{
override fun onItemClick(p0: View?) {
}
})
如果你想用单一方法分配接口,你可以这样写:
adapter.setItemClickListener { view ->
/* some code here */
}
甚至更好:
adapter.setItemClickListener {
/* some code here, to use "view" use keyword "it" */
}
如果您想更深入地了解,让我们分析一下您的方法的签名:
public fun setItemClickListener(itemClickListener: OnItemClickListener)
这实际上等于
public fun setItemClickListener(singleMethodListener: (View) -> Unit)
如果你的最后一个参数是函数,你可以忘记'()',并传递lambda。 再举一个例子:
public fun setItemClickListener(parameter: Int, singleMethodListener: (View) -> Unit)
要调用上面的方法,您的代码应该是:
item.setItemClickListener(0) { /* lambda here */ }
问题是当你有不止一种方法的接口时,因为那样你就不能传递 lambda :(
示例:
interface OnItemClickListener {
fun onItemClick(view: View)
fun onDoubleItemClick(view: View)
}
那么,你不能通过sample labda,因为你必须定义2个方法。然后,你必须像 java 一样做同样的事情,但在其他语法中:
adapter.setItemClickListener(object : OnItemClickListener {
/* method declarations here, like in java */
})
我希望我已经解释了 Kotlin 中的 base-lambda 语法 :D 有任何问题吗?问 ;)
问题是您的界面是在 Kotlin 中定义的(因为它具有 fun
)。 Lambdas can only be used for Java interfaces:
Also note that this feature works only for Java interop; since Kotlin has proper function types, automatic conversion of functions into implementations of Kotlin interfaces is unnecessary and therefore unsupported.
所以在 Kotlin 中你应该使用
public fun setItemClickListener(itemClickListener: (View) -> Unit)
而不是定义 OnItemClickListener
。您还可以创建一个工厂方法:
// in Adapter's companion object
public inline fun OnItemClickListener(body: (View) -> Unit) = object : OnItemClickListener {
override fun onItemClick(view: View) { body(view) }
}
然后
adapter.setItemClickListener(Adapter.OnItemClickListener { view -> ... })