Следующий код взят из примеров архитектуры проекта, вы можете увидеть его здесь .
В TasksFragment.kt текст снэк-бара будет отображаться, когда viewModel.snackbarText
имеет был изменен.
Я не понимаю, почему автор хочет добавить var hasBeenHandled
в class Event<out T>
.
Я думаю, что var hasBeenHandled
в _snackbarText
будет назначено как true
после запуска getContentIfNotHandled()
, поэтому getContentIfNotHandled()
никогда не будет запущен снова, поэтому я думаю, что снэк-бар будет активирован только один раз.
На самом деле, текст закусочной может отображаться при изменении viewModel.snackbarText
, что со мной?
Event.kt
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
}
TasksFragment.kt
private fun setupSnackbar() {
view?.setupSnackbar(this, viewModel.snackbarText, Snackbar.LENGTH_SHORT)
arguments?.let {
viewModel.showEditResultMessage(args.userMessage)
}
}
ViewExt.kt
fun View.setupSnackbar(
lifecycleOwner: LifecycleOwner,
snackbarEvent: LiveData<Event<Int>>,
timeLength: Int
) {
snackbarEvent.observe(lifecycleOwner, Observer { event ->
event.getContentIfNotHandled()?.let {
showSnackbar(context.getString(it), timeLength)
}
})
}
fun View.showSnackbar(snackbarText: String, timeLength: Int) {
Snackbar.make(this, snackbarText, timeLength).run {
addCallback(object : Snackbar.Callback() {
override fun onShown(sb: Snackbar?) {
EspressoIdlingResource.increment()
}
override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
EspressoIdlingResource.decrement()
}
})
show()
}
}
TasksViewModel.kt
class TasksViewModel(
private val tasksRepository: TasksRepository,
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
private val _snackbarText = MutableLiveData<Event<Int>>()
val snackbarText: LiveData<Event<Int>> = _snackbarText
fun showEditResultMessage(result: Int) {
if (resultMessageShown) return
when (result) {
EDIT_RESULT_OK -> showSnackbarMessage(R.string.successfully_saved_task_message)
ADD_EDIT_RESULT_OK -> showSnackbarMessage(R.string.successfully_added_task_message)
DELETE_RESULT_OK -> showSnackbarMessage(R.string.successfully_deleted_task_message)
}
resultMessageShown = true
}
...
}