可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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) return@OnClickListener
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?
回答1:
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
}
回答2:
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
}
回答3:
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
回答4:
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")
}
then use like:
performWork("http://..."){ result ->
//use result
}
回答5:
First of all you need to remove this code:
mCircleShape.setOnClickListener(View.OnClickListener {
if (listener == null) return@OnClickListener
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.
回答6:
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") }
)