Навигация изнутри ViewModel
будет означать, что вам нужен экземпляр представления, который идет вразрез с концепцией MVVM. Вместо этого используйте LiveData
, чтобы указать вашему фрагменту, что ему нужно перейти к следующему пункту назначения. Вы можете использовать следующий класс Event
(из одного из примеров архитектуры ) от Google, чтобы убедиться, что навигация срабатывает только один раз.
open class Event<out T>(private val content: T) {
@Suppress("MemberVisibilityCanBePrivate")
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
}
Используйте его с этим Observer
:
/**
* An [Observer] for [Event]s, simplifying the pattern of checking if the [Event]'s content has
* already been handled.
*
* [onEventUnhandledContent] is *only* called if the [Event]'s contents has not been handled.
*/
class EventObserver<T>(private val onEventUnhandledContent: (T) -> Unit) : Observer<Event<T>> {
override fun onChanged(event: Event<T>?) {
event?.getContentIfNotHandled()?.let {
onEventUnhandledContent(it)
}
}
}
Это ваш LiveData
:
private val _openTaskEvent = MutableLiveData<Event<String>>()
val openTaskEvent: LiveData<Event<String>> = _openTaskEvent
И, наконец, вы можете наблюдать это так:
viewModel.openTaskEvent.observe(this, EventObserver {
//Do your navigation here
})