我观察到观察者的MutableLiveData触发器onChanged,即使为其setValue方法提供了相同的对象实例也是如此。
//Fragment#onCreateView - scenario1
val newValue = "newValue"
mutableLiveData.setValue(newValue) //triggers observer
mutableLiveData.setValue(newValue) //triggers observer
//Fragment#onCreateView - scenario2
val newValue = "newValue"
mutableLiveData.postValue(newValue) //triggers observer
mutableLiveData.postValue(newValue) //does not trigger observer
Run Code Online (Sandbox Code Playgroud)
如果向setValue()/ 提供了相同或等效的实例,是否有办法避免两次通知观察者postValue()
我尝试扩展,MutableLiveData但是没有用。我可能在这里错过了一些东西
class DistinctLiveData<T> : MutableLiveData<T>() {
private var cached: T? = null
@Synchronized override fun setValue(value: T) {
if(value != cached) {
cached = value
super.setValue(value)
}
}
@Synchronized override fun postValue(value: T) {
if(value != cached) { …Run Code Online (Sandbox Code Playgroud) 我的代码
fun weatherByCity(cityName: String): LiveData<Resource<Response>> = liveData(Dispatchers.IO) {
val response = appRepository.weatherByCity(cityName)
emit(response)
}
fun weatherByZipCode(zipCode: String): LiveData<Resource<Response>> = liveData(Dispatchers.IO) {
val response = appRepository.weatherByZipCode(zipCode)
emit(response)
}
fun weatherByLocation(latLong: String): LiveData<Resource<Response>> = liveData(Dispatchers.IO) {
val response = appRepository.weatherByLocation(lat?:"", long?:"")
emit(response)
}
Run Code Online (Sandbox Code Playgroud)
在这里,我使用了三个 liveData{} 块,它们从存储库中获取数据并进行改造。但它们具有相同的返回类型LiveData<Resource<Response>>。我可以对所有三个都使用单个 liveData{},如果是,那么该怎么做?还有一个问题,使用 liveData(Dispatchers.IO) 还是使用 liveData{}(不使用 Dispatchers.IO)会有什么不同?
android kotlin android-livedata mutablelivedata kotlin-coroutines
在我的项目中,我使用了一个稍微修改的存储库模式:
在我的存储库中,我使用公开的 LiveData<*> 字段来传达状态 - 例如,说 UserRepository 将有一个currentUser公共类型 LiveData的字段,私有的 MediatorLiveData,它将链接到一个私有字段,该字段包含要检索的当前用户 ID。
但是,addSource() {}由于某种原因,这些订阅(使用 MediatorLiveData 的方法)不会触发。
一个几乎 1:1 的例子(由于 NDA 替换了模型名称)如下:
abstract class BaseRepository: ViewModel(), KoinComponent {
val isLoading: LiveData<Boolean> = MutableLiveData<Boolean>().apply { postValue(false) }
}
class UserRepository: BaseRepository() {
private val client: IClient by inject() // Koin injection of API client
private val sharedPref: SharedPrefManager by inject() // custom wrapper …Run Code Online (Sandbox Code Playgroud) 请帮帮我。
我想使用LiveData.
OnChanged()在应用程序启动时触发一次,但是当我string1通过单击按钮更改值时,onChange()不会触发并且信息不会更新。TextView一直显示“哇”
我完全按照这里的描述做所有事情。
的ViewModel:
class CurrentViewModel : ViewModel() {
val currentName: MutableLiveData<String> by lazy {
MutableLiveData<String>()
}
}
Run Code Online (Sandbox Code Playgroud)
片段:
class CurrentFragment : Fragment(R.layout.current_fragment) {
private val viewModel: CurrentViewModel by viewModels()
var string1 = "Wow!"
override fun onActivityCreated(savedInstanceState: Bundle?)
val nameObserver = Observer<String> { newName ->
textview.text = newName }
viewModel.currentName.value = string1
viewModel.currentName.observe(activity!!, nameObserver)
button.setOnClickListener {
string1 = "some new string"
}
}
Run Code Online (Sandbox Code Playgroud) 在以下示例中,我想公开这样的 Int 列表:
val test: LiveData<List<Int>>
get() = _test as LiveData<List<Int>>
private var _test = MutableLiveData(mutableListOf<Int>())
Run Code Online (Sandbox Code Playgroud)
或另一种口味:
private var _test2 = MutableLiveData(mutableListOf<Int>())
val test2 = _test2 as LiveData<List<Int>>
Run Code Online (Sandbox Code Playgroud)
两者都在工作,但总是有一个未经检查的演员。
Unchecked cast: MutableLiveData<MutableList<Int>!> to LiveData<List<Int>>
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来做到这一点?
只是为了澄清:
通过使用 emptyList,用法可能如下所示:
class MainViewModel : ViewModel() {
val test: LiveData<List<Int>> get() = _test
private var _test = MutableLiveData(emptyList<Int>())
init {
val myPrivateList = mutableListOf<Int>()
myPrivateList.add(10)
myPrivateList.add(20)
_test.value = myPrivateList
}
}
Run Code Online (Sandbox Code Playgroud)
我希望找到一种无需额外列表(myPrivateList)的方法,如下所示:
class MainViewModel : ViewModel() {
val test: LiveData<List<Int>> get() = _test
private …Run Code Online (Sandbox Code Playgroud) 无需ViewModel()仅使用简单的类进行扩展,我就可以实现 LiveData 和 DataBinding 示例,但我在 google 开发人员文档中显示了扩展ViewModel()以创建 LiveData 对象。那么为什么我们需要扩展它呢?
https://developer.android.com/topic/libraries/architecture/livedata