Как я могу использовать обратный вызов в Котлине?
У меня есть View и один CircleShape, который должен показывать тост в этом представлении. И я использую его в основной деятельности. Это мой интерфейс
interface OnClickListenerInterface {
fun onClick()
}
Это CircleShape (это View in my xml) и прослушиватель в моем представлении. Я хочу реализовать OnClick в своей работе.
var listener: OnClickListenerInterface? = null
mCircleShape.setOnClickListener(View.OnClickListener {
if (listener == null) [email protected]
listener!!.onClick()
})
Я знаю, что в Kotlin получатели и сеттеры генерируют автоматику, но как я могу установить слушателя, если он частный. Это код из моей активности, но он не работает
CircleShape.listener = object :OnClickListenerInterface{
override fun onClick() {
ToastUtils.showSuccessMessage(getContext(),"pressed")
}
}
Как я должен использовать Callback, onClickListenere в Котлине?
Ответы
Ответ 1
Более простое решение с использованием лямбды.
Внутри CircleShape.kt объявите лямбда-функцию.
var listener: (()->Unit)? = null
...
// When you want to invoke the listener
listener?.invoke()
Внутри вашей деятельности
mCircleShape.listener = {
// Do something when you observed a call
}
Ответ 2
На CircleShape.kt.
private listener OnClickListenerInterface? = null
...
fun setOnClickListener(listener: OnClickListenerInterface){
this.listener = listener
}
О вашей активности
mCircleShape.setOnClickListener(object: CircleShape.OnClickListenerInterface {
override fun onClick(){ // Do something here
}
}
Если вы собираетесь использовать лямбда-выражение, вы можете использовать тип функции. Вот как это выглядит
на CirclesShapt.kt
fun setOnClickListener(listener: () -> Unit){
listener() // or you could use optional if the lister is nullable "listener?.invoke()"
}
Так в действии выглядит так.
mCircleShape.setOnClickListener {
// Do something here
}
Ответ 3
использовать обратные вызовы 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")
}
}
for toast("message"), use Anko Lib from GitHub: - https://github.com/Kotlin/anko
Ответ 4
определите функцию следующим образом:
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
}
Ответ 5
Прежде всего, вам нужно удалить этот код:
mCircleShape.setOnClickListener(View.OnClickListener {
if (listener == null) [email protected]
listener!!.onClick()
})
Поскольку слушатель сначала всегда имеет значение null, а ваш код всегда возвращается.
var listener: OnClickListenerInterface? = null
var listener: OnClickListenerInterface? = null
уже является общедоступным (это уровень доступа по умолчанию в Котлине). Поэтому вы можете просто установить его в своей деятельности, когда это необходимо. listener?.onClick()
чтобы вызвать его из CircleShape.
Ответ 6
Вы пытались использовать лямбда-выражение? Например, в вашем случае:
mCircleShape.setOnClickListener(
{ _ -> ToastUtils.showSuccessMessage(context,"pressed") }
)
Или, если вы хотите сделать его более стилем kotlin:
mCircleShape.listener = (
{ _ -> ToastUtils.showSuccessMessage(context,"pressed") }
)