我如何在Kotlin中使用回调?

man*_*ing 21 java xml android listener kotlin

我有View和一个CircleShape,它应该在此视图中显示吐司.我在主Activity中使用它.这是我的界面

interface OnClickListenerInterface {
  fun onClick()
}
Run Code Online (Sandbox Code Playgroud)

它是我的视图中的CircleShape(在我的xml中是View)和监听器.我想在我的Activity中实现OnClick.

 var listener: OnClickListenerInterface? = null

 mCircleShape.setOnClickListener(View.OnClickListener {
      if (listener == null) return@OnClickListener
      listener!!.onClick()
    })
Run Code Online (Sandbox Code Playgroud)

我知道,在Kotlin getter和setter通用自动机,但我如何设置监听器,如果它是私有的.它是我的Activity的代码,但它不起作用

CircleShape.listener  = object :OnClickListenerInterface{
      override fun onClick() {
        ToastUtils.showSuccessMessage(getContext(),"pressed")
      }
    }
Run Code Online (Sandbox Code Playgroud)

我应该如何在Kotlin中使用Callback,onClickListenere?

Dan*_*anu 30

定义一个这样的函数:

  fun performWork(param1: String, myCallback: (result: String?) -> Unit) {
    // perform some network work

    // on network finished
    myCallback.invoke("result from network")
  }
Run Code Online (Sandbox Code Playgroud)

像这样使用:

  performWork("http://..."){ result ->
  //use result
  }
Run Code Online (Sandbox Code Playgroud)


Wei*_*ang 19

通过使用lambda,这是一种更简单的解决方案。

在CircleShape.kt中,声明一个lambda函数。

var listener: (()->Unit)? = null
...
// When you want to invoke the listener
listener?.invoke()
Run Code Online (Sandbox Code Playgroud)

内部活动

mCircleShape.listener = {
    // Do something when you observed a call
}
Run Code Online (Sandbox Code Playgroud)


dr3*_*r3k 15

在CircleShape.kt上.

private listener OnClickListenerInterface? = null
...
fun setOnClickListener(listener: OnClickListenerInterface){
    this.listener = listener
}
Run Code Online (Sandbox Code Playgroud)

在你的活动上

mCircleShape.setOnClickListener(object: CircleShape.OnClickListenerInterface {
    override fun onClick(){ // Do something here
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您要使用lambda表达式,则可以使用函数类型.这是它在CirclesShapt.kt上的样子

fun setOnClickListener(listener: () -> Unit){
   listener() // or you could use optional if the lister is nullable "listener?.invoke()"
}
Run Code Online (Sandbox Code Playgroud)

所以在活动中看起来像.

mCircleShape.setOnClickListener {
  // Do something here
}
Run Code Online (Sandbox Code Playgroud)

  • 您的第二个解决方案没有演示 CirclesShapt.kt 中的 setOnClickListener 假设如何调用侦听器。 (4认同)

小智 6

要使用Kotlin回调,我会在api调用中使用它们来成功或失败使用

为状态创建枚举类

enum class APIState(val result: Boolean) {
SUCCESS(true),
FAILURE(false)}
Run Code Online (Sandbox Code Playgroud)

有趣地使用回电

 private fun fetchFeesList(studentID:String,call:(APIState)->Unit){
 ... do stuff here , and use call(APIState.SUCCESS) or call(APIState.FAILURE) }
Run Code Online (Sandbox Code Playgroud)

调用函数fetchFeesList时,像这样调用它

fetchFeesList(studentID){
        val res = it.result
        if(res){
            toast("success")
        }else {
            toast("failure")
        }
    }
Run Code Online (Sandbox Code Playgroud)

对于toast(“ message”),请使用来自GitHub的Anko Lib:-https: //github.com/Kotlin/anko


小智 5

我一直在拼命寻找类似于 Java 接口提供的 Kotlin 解决方案,直到我遇到了上面提供的建议。在尝试了所有这些之后,我无法找到适合我的场景的可行解决方案。

这导致我自己的实现完美地根据我的用例工作,因此我认为我可以在这里分享相同的内容,尽管这可能不是完美的方式,提前道歉。

步骤:

  • 1. 定义您的界面:
interface OnClickListenerInterface {
    fun onClick()
}
Run Code Online (Sandbox Code Playgroud)
  • 2. 在将触发“onClick”回调的类中,即您的情况的“CircleShape”:

创建一个可为空的变量。

var listener: OnClickListenerInterface? = null
Run Code Online (Sandbox Code Playgroud)

声明一个函数来初始化上面的变量。

fun initOnClickInterface(listener: OnClickListenerInterface){
        this.listener = listener
    }
Run Code Online (Sandbox Code Playgroud)

在您想要触发“onClick”回调的位置:

mCircleShape.setOnClickListener(View.OnClickListener {
      if (listener == null) return@OnClickListener
      listener?.onClick() // Trigger the call back
    })
Run Code Online (Sandbox Code Playgroud)
  • 3. 在您想要接收“onClick”回调的活动内部:

使活动实现 OnClickListenerInterface,然后创建 CircleShape 类的对象。

class Activity : AppCompatActivity(), OnClickListenerInterface {
    val mCircleShape = CircleShape()
    // ...other stuff
Run Code Online (Sandbox Code Playgroud)

在此活动的 onCreate 函数中,使用我们在 CircleShape 类中创建的 initOnClickInterface 函数初始化您的界面。

mCircleShape.initOnClickListenerInterface(this)
Run Code Online (Sandbox Code Playgroud)

然后通过在活动中添加以下代码来重写界面的 onClick 方法来完成。

override fun onClick() {
        // Callback received successfully. Do your stuff here
    }
Run Code Online (Sandbox Code Playgroud)

上述步骤对我有用。

正如我所说,如果我的编码出现任何问题,我也是一个学习者。

干杯!


Yev*_*ets 0

首先,您需要删除此代码:

mCircleShape.setOnClickListener(View.OnClickListener {
      if (listener == null) return@OnClickListener
      listener!!.onClick()
    })
Run Code Online (Sandbox Code Playgroud)

因为侦听器一开始总是为空,并且您的代码总是返回。

var listener: OnClickListenerInterface? = null已经是公开的(这是 Kotlin 中的默认访问级别)。因此,您可以在需要时将其设置在您的活动中。使用listener?.onClick()call 从 CircleShape 中触发它。