gpt4 book ai didi

android - 如何在 Android 中以正确的方式观察多个 observe 的 livedata?

转载 作者:行者123 更新时间:2023-11-29 02:18:34 25 4
gpt4 key购买 nike

我有一个 Activity,它会转向 fragment-A,然后转向 fragment-B,如下所示。

Activity -> Fragment-A -> Fragment-B

情况一

这两个 fragment 观察相同的 LiveData 来显示 snackBar,如下所示。

viewModel.responseData.observe(this, Observer {
it.getContentIfNotHandled()?.let {
showSnackBar(it)
}

viewModel 中的livedata:

var responseData = MutableLiveData<Event<String>>()
responseData.value = Event("$message")

错误:当我使用上面的代码时。它仅在 fragment-A 处显示 snackBarfragment-B取不到值。

情况2

当我将代码更改为以下内容时

viewModel.responseData.observe(this, Observer {
showSnackBar(it.peekContent())
})

both fragment 都能取到值。

错误:

关闭 fragment 后再次转动。它显示 snackBar,因为 responseData 的值仍然存在。但是我没有发送消息。

来自 Google 的

Event 类引用如下:

/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package bbin.mobile.ballbet.support

import androidx.lifecycle.Observer
import timber.log.Timber

/**
* 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
}

/**
* 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)
}
}
}

我希望 fragment 为他们显示正确的 snackBar 消息。

如何在 Android 中观察多个 fragment 的 livedata 以正确的方式?

提前致谢。

最佳答案

您正在正确观察 LiveData,这就是 Event 的方式类(class)设计。

当你这样做的时候

viewModel.responseData.observe(this, Observer {
it.getContentIfNotHandled()?.let {
showSnackBar(it)
}

getContentIfNotHandled将只返回一次内容,直到再次设置新值。如果FragmentA先消费这个FragmentB将无法消费相同的值(value)。这就是原因peekContent有效,因为即使事件已被消耗,它也将始终返回当前值。

如果有充分的理由需要在两个 fragment 中显示此 Snackbar 消息,我建议您观察不同的 LiveData每个 fragment 的实例。

您可以通过返回一个新的 LiveData<Event<String>> 来做到这一点每次viewModel.getResponseData()被调用。

关于android - 如何在 Android 中以正确的方式观察多个 observe 的 livedata?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58074855/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com