android 观察创建片段时调用的LiveData

ie3xauqp  于 2023-01-07  发布在  Android
关注(0)|答案(3)|浏览(137)

简而言之:当Observe处于活动状态时,它在我发出通知时正常工作,但当我返回到上一个片段(我使用导航组件)并再次导航到当前片段时,会创建片段,并且出于某种原因,Observe会被调用。
为什么在返回时没有删除Observe?它应该根据片段的生命周期进行操作。我尝试在onStop上删除,但仍然调用了Observe。
更多详情:我的每个项目片段分为3个部分:在视图部分,我首先设置了viewModel。

class EmergencyFragment : Fragment() {

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       emergencyFragmentViewModel = ViewModelProviders.of(this).get(EmergencyFragmentViewModel::class.java)
   }

在onViewCreated中,我设置了Observer对象,以便在LiveData中所做的任何更改都会在此处收到更改通知:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
   super.onViewCreated(view, savedInstanceState)
   emergencyFragmentViewModel.isEmergencyEventMediaLDSuccess.observe(viewLifecycleOwner, Observer {
       Log.d("sendEmergencyEvent", "isEmergencyEventMediaLDSuccess observer called")
       }
   })
}

在ViewModel类中,我按如下方式设置LiveData参数:

EmergencyFragmentViewModel: ViewModel() {
   var isEmergencyEventMediaLDSuccess: LiveData<Boolean> = MutableLiveData()
       private set
   private val observerEventMedia = Observer<Boolean> { (isEmergencyEventMediaLDSuccess as MutableLiveData).value = it}

在init中我设置了一个观察者:

init {
   EmergencyFragmentModel.isEmergencyEventMediaLDSuccessModel.observeForever(observerEventMedia)
}

当然也会在需要时移除

override fun onCleared() {
   super.onCleared()
   EmergencyFragmentModel.isEmergencyEventMediaLDSuccessModel.removeObserver(observerEventMedia)
}

模型的零件定义如下:

class EmergencyFragmentModel {
   companion object{
       val isEmergencyEventMediaLDSuccessModel: LiveData<Boolean> = MutableLiveData()

我确实请求网络,当收到回复时,我会执行通知

override fun onResponse(call: Call<Int>, response: Response<Int>) {
   if(response.isSuccessful) {
       (isEmergencyEventLDModelSuccess as MutableLiveData).postValue(true)
       Log.d("succeed", "sendEmergencyEvent success: ${response.body().toString()}")
   }

有人能告诉我我错过了什么吗?为什么当有一个活动的观察,我回到以前的片段(我使用了导航组件)并再次导航到当前片段,Observe就被调用了?我可以理解,当一个ViewModel示例被创建,并且它为LiveData参数执行setValue时,然后就通知了。但是为什么我回去的时候没有删除观察呢?我试着删除onstop上的观察,结果一直发生。

override fun onStop() {
        super.onStop()
        emergencyFragmentViewModel.isEmergencyEventMediaLDSuccess.removeObservers(viewLifecycleOwner)
        emergencyFragmentViewModel.isEmergencyEventMediaLDSuccess.removeObserver(observeEmergencyEventLDSuccess)
    }
cetgtptt

cetgtptt1#

@Pawel是对的,LiveData存储了值,每次你观察它(在本例中是在onViewCreated中),它都会发出最后存储的值。
也许您需要类似于SingleLiveEvent的代码,它可以在用户读取它之后清除它的值。
因此,当您来回切换时,它不会发出最后一个值(一旦它被清除)。

eiee3dmh

eiee3dmh2#

根据我对您问题的理解,您只希望在新值与旧值不同时运行观察器,这可以通过在viewModel中的另一个变量中保留该值来实现。

if (newValue == viewModel.retainedValue) return@observe
    viewModel.retainedValue = newValue
a5g8bdjr

a5g8bdjr3#

我通过检入生命周期状态在Kotlin中创建一个扩展来修复这个问题。

fun <T> LiveData<T>.observeOnResumedState(viewLifecycleOwner: LifecycleOwner, observer: Observer<T>) {
    this.observe(viewLifecycleOwner) {
        if (viewLifecycleOwner.lifecycle.currentState == Lifecycle.State.RESUMED) {
            observer.onChanged(it)
        }
    }
}

这是我观察到的

viewModel.result.observeOnResumedState(viewLifecycleOwner) {
    // TODO
}

相关问题