Как передать функцию обратного вызова, которая возвращает LiveData с использованием Kotlin лямбда-выражений? - PullRequest
0 голосов
/ 21 июня 2020

В Android у меня есть ListAdapter, которому я передаю обратные вызовы, используя лямбда-нотацию Kotlin.

Например, ListAdapter имеет:

var clickCallback = { _: Long  -> Unit }

Что устанавливается во фрагменте, вызывающем ListAdapter с помощью:

mAdapter.clickCallback = {id: Long -> selectItem(id)}

Эта функция фрагмента selectItem(id: Long) затем вызывается внутри ListAdapter с помощью:

clickCallback(item.id) 

Но что, если эта переданная функция selectItem() вернул значение, например LiveData, а что, если бы я хотел вызвать эту функцию и наблюдать за LiveData изнутри адаптера? Я не могу, хоть убей, понять, как передать такую ​​функцию, чтобы можно было наблюдать функцию обратного вызова внутри ListAdapter.

Это даже близко не работает, но, надеюсь, это должно дать вам представление о том, какое решение я ищу:

var clickCallback:LiveData<String> = { _: Long  -> Unit?? }
....
clickCallback(item.id).observe(holder.ItemView, Observer { answerString -> 
    doSomethingTo(answerString)
})

Бонусные баллы, если вы знаете, как получить viewLifecycleOwner внутри ListAdapter. Я просто догадываюсь, что это держатель.ItemView.

Спасибо!

Джон

1 Ответ

2 голосов
/ 21 июня 2020

Создать обратный вызов, возвращающий объект, очень просто. Просто используйте следующий синтаксис для лямбда-типа:

var callback: (([Params]) -> ReturnType)? = null

И код:

var clickCallback: ((Long) -> LiveData<String>)? = null

clickCallback?.invoke(item.id)?.observe(holder.ItemView, Observer { answerString ->
    doSomethingTo(answerString)
})

Если вы хотите обратный вызов с реализацией по умолчанию, он будет:

var clickCallback: (Long) -> LiveData<String> = { _: Long  -> MutableLiveData() }

clickCallback(item.id).observe(holder.ItemView, Observer { answerString ->
    doSomethingTo(answerString)
})

Бонусные баллы, если вы знаете, как получить viewLifecycleOwner внутри ListAdapter. Я просто предполагаю, что это держатель.ItemView.

Этого можно добиться, передав viewLifecycleOwner в качестве параметра конструктора:

    // adapter definition
    class YourAdapter(private val lifecycleOwner: LifecycleOwner) ...
    
    // passing viewLifecycleOwner as constructor parameter
    val adapter = YourAdapter(viewLifecycleOwner)

Теперь вы можете получить доступ к lifecycleOwner недвижимость внутри YourAdapter.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...