【问题标题】:How I can use callback in Kotlin?如何在 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 部分。谢谢
  • 这里有一些解决方案:stackoverflow.com/a/56608847/753632

标签: java android xml kotlin listener


【解决方案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 触发它。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-05-20
              • 2020-01-10
              • 1970-01-01
              • 2019-05-01
              • 2021-01-14
              • 2018-12-05
              相关资源
              最近更新 更多