как избежать повторения повторенияOnLifecycle снова и снова при возобновлении фрагмента
как я могу избежать повторного выполнения кода collect{} при возвращении к фрагменту.
ViewModel класс
private val _commitResult = MutableStateFlow<Map<String, Any>>(mapOf())
val commitResult: StateFlow<Map<String, Any>> = _commitResult
Fragment code like this:
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED){
viewModel.commitResult.collect { data ->
Logger.i("commitResult $data")
//navigate to another fragment
}
}
}
когда я сначала меняю значение _commitResult в viewModel, переход к другому фрагменту работает нормально. к сожалению, когда я вернусь к фрагменту.
collect{ // navigate to another fragment}
снова изгоню.
Я знаю, когда вернусь к фрагменту. onCreateView, и viewModel выдаст хранилище данных раньше, поэтому
collect { // navigate to another fragment}
извинить. Как мне этого избежать?
так же, как LiveData, я использую Event, чтобы исправить это с помощью LiveData.
open class Event<out T>(private val content: T) {
var hasBeenHandled = false
private set // Allow external read but not write
/**
* Returns the content and prevents its use again.
*/
fun getContentIfNotHandled(): T? {
return if (hasBeenHandled) {
null
} else {
hasBeenHandled = true
content
}
}
/**
* Returns the content, even if it's already been handled.
*/
fun peekContent(): T = content
}
как я могу справиться с этим с помощью Stateflow? на самом деле мне не нравится, когда Event<.> обрабатывает это, я неправильно использую поток состояний? как я могу это исправить? Если кто может помочь, заранее спасибо.
1 ответ
StateFlow сохраняет свое состояние, поэтому я бы предложил:
А) Использование
SharedFlow
. https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-shared-flow/
B) Используйте шаблон, в котором вы обрабатываете отклонение событий
class Vm: ViewModel() {
private val mEvent = MutableStateFlow<MyResult?>(null)
val event = mEvent.asStateFlow()
fun dismissEvent() {
mEvent.value = null
}
}
class Frag: Fragment() {
override fun onViewCreated() {
vm.event.collect {
navigate()
vm.dismissEvent()
}
}
}