Ответ
LiveData с SingleEvent оберткой – самый популярный способ. Используем Event класс-обертку:
class Event<out T>(private val content: T) {
private var hasBeenHandled = false
fun getContentIfNotHandled(): T? {
return if (hasBeenHandled) null
else {
hasBeenHandled = true
content
}
}
}
// В ViewModel
private val _event = MutableLiveData<Event<String>>()
val event: LiveData<Event<String>> = _event
fun triggerEvent() {
_event.value = Event("Message")
}
// Во Fragment
viewModel.event.observe(viewLifecycleOwner) { event ->
event.getContentIfNotHandled()?.let { message ->
showToast(message)
}
}
Альтернативы:
- SharedFlow с replay=0 (одноразовые события)
- Channels (устаревший способ)
- RxJava Single/Completable
Главное преимущество Event-обертки – гарантия однократной обработки события даже при смене конфигурации.