TransWikia.com

How to compare two LiveData whether they are equal in Android Studio?

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

One Answer

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 LiveDatas:

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

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP