Stack Overflow Asked by HelloCW on October 29, 2020
I have two LiveData
, aMVoice1
, and aMVoice2
.
I hope to check if they are equal.
I know I need to use observe
to get the value of a LiveData.
so I think isEqual = (mDetailViewModel.aMVoice1.value==mDetailViewMode2.aMVoice1.value )
is wrong.
But I think there are some problems with fun observeVoice()
, how can I fix it?
class FragmentDetail : Fragment() {
private lateinit var binding: LayoutDetailBinding
private val mDetailViewModel by lazy {
...
}
var isEqual=false
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
...
binding.lifecycleOwner = this.viewLifecycleOwner
binding.aDetailViewModel=mDetailViewModel
isEqual = (mDetailViewModel.aMVoice1.value==mDetailViewMode2.aMVoice1.value ) // I don't think it's correct.
observeVoice()
return binding.root
}
fun observeVoice() {
mDetailViewModel.aMVoice1.observe(viewLifecycleOwner){value1->
isEqual = (value1==mDetailViewModel.aMVoice2.value) // mDetailViewModel.aMVoice2.value maybe null
}
}
}
class DetailViewModel(private val mDBVoiceRepository: DBVoiceRepository, private val voiceId1:Int,private val voiceId2:Int) : ViewModel() {
val aMVoice1=mDBVoiceRepository.getVoiceById(voiceId1)
val aMVoice2=mDBVoiceRepository.getVoiceById(voiceId2)
}
class DBVoiceRepository private constructor(private val mDBVoiceDao: DBVoiceDao){
fun getVoiceById(id:Int)=mDBVoiceDao.getVoiceById(id)
}
@Dao
interface DBVoiceDao{
@Query("SELECT * FROM voice_table where id=:id")
fun getVoiceById(id:Int):LiveData<MVoice>
}
data class MVoice(
@PrimaryKey (autoGenerate = true) @ColumnInfo(name = "id") var id: Int = 0,
var name: String = "",
var path: String = ""
)
Added Content
Is it Ok for the following code?
fun observeVoice() {
mDetailViewModel.aMVoice1.observe(viewLifecycleOwner){value1->
mDetailViewModel.aMVoice2.observe(viewLifecycleOwner){value2->
isEqual = (value1==value2)
}
}
}
According to the official documents, the best way to achieve a solution for such cases is to use MediatorLiveData
as a LiveData
merger. Using it, you can check the equality of values when a new value is posted on either of LiveData
s:
class DetailViewModel(...) : ViewModel() {
val areMVoicesEqual = MediatorLiveData<Boolean>().apply {
addSource(aMVoice1) { postValue(it == aMVoice2.value) }
addSource(aMVoice2) { postValue(it == aMVoice1.value) }
}
}
Then:
fun observeVoice() {
mDetailViewModel.areMVoicesEqual.observe(viewLifecycleOwner){ equality ->
// do whatever you want with `equality`
}
}
Note that Added Content snippet you mentioned is not correct. In fact, in this case, every time a value is being observed on aMVoice1
, a new Observer
starts to observe on aMVoice2
which is not right.
Answered by aminography on October 29, 2020
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP