Home » Android » java – How I can use callback in Kotlin?

java – How I can use callback in Kotlin?

Posted by: admin April 23, 2020 Leave a comment

Questions:

I have View and one CircleShape , which should show toast in this View. And I use it in main Activity.
This is my interface

interface OnClickListenerInterface {
  fun onClick()
}

It is CircleShape( it is View in my xml) and listener in my View. I want to implement OnClick in my Activity.

 var listener: OnClickListenerInterface? = null

 mCircleShape.setOnClickListener(View.OnClickListener {
      if (listener == null) [email protected]
      listener!!.onClick()
    })

I know , that in Kotlin getters and setters generic automatics, but how I can set listener if it private. It is code from my Activity, but It doesn’t work

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

How I should to use Callback, onClickListenere in Kotlin?

How to&Answers:

A more simpler solution by using lambda.

Inside CircleShape.kt, declare a lambda function.

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

Inside your Activity

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

Answer:

On CircleShape.kt.

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

On your Activity

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

If you’re gonna use lambda expression, you can use a Function Type. Here how it looks like
on CirclesShapt.kt

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

So in activity looks like.

mCircleShape.setOnClickListener {
  // Do something here
}

Answer:

define a function like this:

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

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

use like this:

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

Answer:

to use Kotlin callbacks ,
I use them in my api calls for success or failure
use

create enum class for state

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

use call back in fun

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

when calling function fetchFeesList , call it like

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

for toast(“message”) , use Anko Lib from GitHub : – https://github.com/Kotlin/anko

Answer:

First of all you need to remove this code:

mCircleShape.setOnClickListener(View.OnClickListener {
      if (listener == null) [email protected]
      listener!!.onClick()
    })

Because listener is always null at first and your code just always returns.

var listener: OnClickListenerInterface? = null is already public (this is a default access level in Kotlin). So you can just set it in your activity, when needed. Use listener?.onClick() call to trigger it from your CircleShape.

Answer:

Have you tried to use a lambda expression? For example in your case:

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

Or if you want to make it more kotlin style:

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