从Kotlin调用Java代码时,有SAM conversion所以Java代码如下:
adapter.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view, int position) {
// Do stuff here
}
});
可以这样:
adapter.setOnClickListener { view, position ->
// Do stuff
}
现在,我正在研究Kotlin项目,我想将功能接口定义为事件监听器:
interface OnSomeActionListener {
fun onSomeAction(parameter1: Int, parameter2: String)
}
在SomeClass
中我有一个设置监听器的功能:
...
private var onSomeActionListener: OnSomeActionListener? = null
fun setOnSomeActionListener(listener: OnSomeActionListener) {
onSomeActionListener = listener
}
...
当我创建这个类的实例并尝试调用setter函数时,我这样做:
val thing = SomeClass()
thing.setOnSomeActionListener(object : OnSomeActionListener {
override fun onSomeAction(parameter1: Int, parameter2: String) {
// Do stuff here
}
})
我知道Kotlin有功能类型,因此不支持从this one等各种站点进行SAM转换。
我已经阅读了一些关于功能类型的内容,但我之前没有使用它们。
如何重写代码以便我可以像这样调用setter函数?
val thing = SomeClass()
thing.setOnSomeActionListener { parameter1, parameter2 ->
// Do stuff here
}
答案 0 :(得分:12)
函数类型如下所示:
(Parameters) -> ReturnType
在您的情况下,您可以使用(View, Int) -> Unit
而不是使用接口类型。它看起来像这样:
private var onSomeActionListener: ((View, Int) -> Unit)? = null
fun setOnSomeActionListener(listener: (View, Int) -> Unit) {
onSomeActionListener = listener
}
private fun callSomeActionListener(view: View, position: Int) {
onSomeActionListener?.invoke(view, position)
}
添加名称
在功能类型中,您还可以指定参数的名称。这并没有太大的改变,但它们可以在这里和调用代码中添加一些清晰度,这很好。
(view: View, position: Int) -> Unit
使用类型别名
为避免每次都输入(View, Int) -> Unit
,您可以定义一个类型:
typealias OnSomeActionListener = (view: View, position: Int) -> Unit
这样你的代码现在又像这样:
private var onSomeActionListener: OnSomeActionListener? = null
fun setOnSomeActionListener(listener: OnSomeActionListener?) {
onSomeActionListener = listener
}
并称之为:
val thing = SomeClass()
thing.setOnSomeActionListener { view, position ->
// Do stuff here
}
答案 1 :(得分:0)
嗯,这样的事情:
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR),"static","media")
答案 2 :(得分:0)
如何定义接受函数并返回接口的函数?
fun makeOnSomeActionListener(f: (Int,String) -> Unit) = object : OnSomeActionListener {
override fun onSomeAction(parameter1: Int, parameter2: String) = f(parameter1, parameter2)
}
界面将其工作委托给f
。
然后你可以写
val thing = SomeClass()
thing.setOnSomeActionListener(makeOnSomeActionLisener { parameter1, parameter2 ->
// Do stuff here
})