繁体   English   中英

我如何在 Kotlin 中使用回调?

[英]How I can use callback in Kotlin?

我有 View 和一个 CircleShape,它应该在此 View 中显示 toast。 我在主要活动中使用它。 这是我的界面

interface OnClickListenerInterface {
  fun onClick()
}

它是 CircleShape(它是我的 xml 中的视图)和我的视图中的侦听器。 我想在我的活动中实施 OnClick。

 var listener: OnClickListenerInterface? = null

 mCircleShape.setOnClickListener(View.OnClickListener {
      if (listener == null) return@OnClickListener
      listener!!.onClick()
    })

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

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

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

使用 lambda 的更简单的解决方案。

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

var listener: (()->Unit)? = null
...
// When you want to invoke the listener
listener?.invoke()

在您的活动中

mCircleShape.listener = {
    // Do something when you observed a call
}

在 CircleShape.kt 上。

private listener OnClickListenerInterface? = null
...
fun setOnClickListener(listener: OnClickListenerInterface) {
    this.listener = listener
}

在您的活动中

mCircleShape.setOnClickListener(object: CircleShape.OnClickListenerInterface {
    override fun onClick() {
      // Do something here
    }
})

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

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

所以在活动中看起来像。

mCircleShape.setOnClickListener {
  // Do something here
}

定义一个这样的函数:

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

    // on network finished
    myCallback.invoke("result from network")
  }

像这样使用:

  performWork("http://..."){ result ->
  //use result
  }

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

为状态创建枚举类

enum class APIState(val result: Boolean) {
SUCCESS(true),
FAILURE(false)}

在乐趣中使用回调

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

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

fetchFeesList(studentID){
        val res = it.result
        if(res){
            toast("success")
        }else {
            toast("failure")
        }
    }

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

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

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

步骤:

  • 1. 定义你的接口:
interface OnClickListenerInterface {
    fun onClick()
}
  • 2.在将触发“onClick”回调的类中,即针对您的情况的“CircleShape”:

创建一个可为空的变量。

var listener: OnClickListenerInterface? = null

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

fun initOnClickInterface(listener: OnClickListenerInterface){
        this.listener = listener
    }

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

mCircleShape.setOnClickListener(View.OnClickListener {
      if (listener == null) return@OnClickListener
      listener?.onClick() // Trigger the call back
    })
  • 3. 在要接收“onClick”回调的活动中:

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

class Activity : AppCompatActivity(), OnClickListenerInterface {
    val mCircleShape = CircleShape()
    // ...other stuff

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

mCircleShape.initOnClickListenerInterface(this)

然后通过在活动中添加以下代码来覆盖我们界面的 onClick 方法。

override fun onClick() {
        // Callback received successfully. Do your stuff here
    }

上述步骤对我有用。

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

干杯!

您是否尝试过使用 lambda 表达式? 例如在你的情况下:

mCircleShape.setOnClickListener( 
    { _ -> ToastUtils.showSuccessMessage(context,"pressed") }
)

或者,如果你想让它更像 kotlin 风格:

mCircleShape.listener = ( 
    { _ -> ToastUtils.showSuccessMessage(context,"pressed") }
)

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

mCircleShape.setOnClickListener(View.OnClickListener {
      if (listener == null) return@OnClickListener
      listener!!.onClick()
    })

因为 listener 一开始总是 null 并且您的代码总是返回。

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

经过测试。 这奏效了。

// Define interface
interface MyCallback {
    fun success(param: String)
    fun fail(param: String)
}

fun functionHasCallback(param: Boolean, callback: MyCallback) {
    // do somthing
    if (ok) {
        callback.success("value")
    } else {
        callback.fail("value")
    }
}

// Call function
functionHasCallback(
    boolParam, 
    object: MyCallback {
        override fun success(param: String) {
            // Your code here
        }

        override fun fail(param: String) {
            // Your code here
        }
    }
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM