我有一个 Android 应用程序,当用户执行某些操作(例如删除帖子)时,它会显示吐司,吐司会出现并显示“已删除帖子”,但是如果我们将 Android 手机置于水平位置,吐司会一次又一次地出现,永远不会停止. 我怎样才能让吐司停止?
postsViewModel.genericResponseLiveData.observe(this, Observer {
when (it.status) {
Status.LOADING -> { Timber.e("Loading...") }
Status.SUCCESS -> {
when (it.item) {
GenericResponse.ITEM_RESPONSE.REPORT_POST -> toast("Post reported \uD83D\uDC4A")
else -> Timber.e("Success \uD83D\uDE03")
}
}
Status.ERROR -> { toast("${it.error}. Please try again") }
}
})
} ```
答案 0 :(得分:2)
LiveData 不是为单个事件设计的。
使用 Event
/**
* Used as a wrapper for data that is exposed via a LiveData that represents an event.
*/
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
}
简单的样品使用
class ListViewModel : ViewModel {
private val _navigateToDetails = MutableLiveData<Event<String>>()
val navigateToDetails : LiveData<Event<String>>
get() = _navigateToDetails
fun userClicksOnButton(itemId: String) {
_navigateToDetails.value = Event(itemId) // Trigger the event by setting a new Event as a new value
}
}
活动
myViewModel.navigateToDetails.observe(this, Observer {
it.getContentIfNotHandled()?.let { // Only proceed if the event has never been handled
startActivity(DetailsActivity...)
}
})
使用 Event 将相关部分包装在您的代码中。
答案 1 :(得分:0)
您可以在观察到状态 livedata 后将其设置为 null,如果您的 livedata 为 null,则在观察者内部检查是否为 null,然后返回
答案 2 :(得分:0)
LiveData 本质上是粘性的,这意味着只要您的片段或活动变得活跃,它就会收到最后一个值。因此,它不适用于 1 次事件,例如显示吐司/对话框/小吃店。
您可以像这样使用 SingleLiveEvent:How to use Single Live Event to show toast in Kotlin