如何在 Kotlin 中使用回调?

Posted

技术标签:

【中文标题】如何在 Kotlin 中使用回调?【英文标题】:How I can use callback in Kotlin? 【发布时间】:2018-05-10 00:57:32 【问题描述】:

我有 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 通用自动化中,但如果它是私有的,我如何设置监听器。这是我的 Activity 中的代码,但它不起作用

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

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

【问题讨论】:

“它不起作用” - 什么是错误? 监听器未激活 帮助我实现了回调。我不知道object:OnClickListenerInterface 部分。谢谢 这里有一些解决方案:***.com/a/56608847/753632 【参考方案1】:

使用 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

【讨论】:

【参考方案2】:

定义一个这样的函数:

  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
  

【讨论】:

【参考方案3】:

在 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

【讨论】:

您的第二个解决方案没有演示 CirclesShapt.kt 中的 setOnClickListener 是如何调用监听器的。【参考方案4】:

使用 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

【讨论】:

【参考方案5】:

我一直在拼命寻找类似于 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”回调的 Activity 中:

使活动实现 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
    

以上步骤对我有用。

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

干杯!

【讨论】:

【参考方案6】:

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

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

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

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

【讨论】:

【参考方案7】:

首先你需要删除这段代码:

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

因为 listener 一开始总是为空,而你的代码总是返回。

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

【讨论】:

以上是关于如何在 Kotlin 中使用回调?的主要内容,如果未能解决你的问题,请参考以下文章

如何在可组合函数回调中调用 Kotlin 协程?

如何使用 kotlin 协程处理回调

如何将改造回调响应中的回调从 java 转换为 Kotlin

如何让你的回调更具Kotlin风味

深入理解Kotlin协程如何将回调改写成挂起函数

在 Android 视图模型中的内部网络更改回调时 LiveData 未触发 - Kotlin