Как сравнить два LiveData, равны ли они в Android Studio?

#android #android-livedata

#Android #android-livedata

Вопрос:

У меня есть два LiveData , aMVoice1 и aMVoice2 .

Я надеюсь проверить, равны ли они.

Я знаю, что мне нужно использовать observe , чтобы получить значение LiveData.

поэтому я думаю, isEqual = (mDetailViewModel.aMVoice1.value==mDetailViewMode2.aMVoice1.value ) что это неправильно.

Но я думаю, что есть некоторые проблемы с fun observeVoice() , как я могу это исправить?

 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 = ""
)
  

Добавленный контент

Это нормально для следующего кода?

 fun observeVoice() {
    mDetailViewModel.aMVoice1.observe(viewLifecycleOwner){value1->
       mDetailViewModel.aMVoice2.observe(viewLifecycleOwner){value2->
             isEqual = (value1==value2)
       }
    }
 }
  

Комментарии:

1. Почему бы вам не попробовать наблюдать aMVoice2 в рамках observe aMVoice1

2. для этого вы можете использовать ‘MediatorLiveData’, смотрите Здесь , найдите combineLatestData

3. Спасибо! Хеллиусу, не могли бы вы посмотреть мой добавленный контент в вопросе?

Ответ №1:

Согласно официальным документам, лучший способ достичь решения для таких случаев — использовать MediatorLiveData как LiveData слияние. Используя его, вы можете проверить равенство значений, когда новое значение публикуется в любом из LiveData s:

 class DetailViewModel(...) : ViewModel() {

    val areMVoicesEqual = MediatorLiveData<Boolean>().apply {
        addSource(aMVoice1) { postValue(it == aMVoice2.value) }
        addSource(aMVoice2) { postValue(it == aMVoice1.value) }
    }
}
  

Затем:

 fun observeVoice() {
    mDetailViewModel.areMVoicesEqual.observe(viewLifecycleOwner){ equality ->
       // do whatever you want with `equality`
    }
 }
  

Обратите внимание, что упомянутый вами фрагмент добавленного содержимого неверен. Фактически, в этом случае каждый раз, когда значение наблюдается на aMVoice1 , новое Observer начинает наблюдаться на aMVoice2 , что неверно.