【问题标题】:Observer is not called on LiveData changeLiveData 更改不调用观察者
【发布时间】:2020-02-24 21:12:58
【问题描述】:

我有一个狗列表,当我点击列表中的特定狗时,我可以看到详细信息。但是,由于某种原因,文本视图(dogName、dogPurpose、dogLifespan 等)没有更新。详细信息片段仅显示 XML 布局给出的默认值。可能是什么问题呢?

class DetailFragment : Fragment() {

    private var dogUuid = 0
    private lateinit var viewModel: DetailViewModel

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        arguments?.let {
            dogUuid = DetailFragmentArgs.fromBundle(it).dogUuid
        }

        viewModel = ViewModelProviders.of(this).get(DetailViewModel::class.java)
        viewModel.fetch(dogUuid)

        observeViewModel()
    }

    private fun observeViewModel(){
        viewModel.dogLiveData.observe(this, Observer{ dog ->
            dog?.let {
                dogName.text = dog.dogBreed
                dogPurpose.text = dog.bredFor
                dogTemperament.text = dog.temperament
                dogLifespan.text = dog.lifeSpan
                context?.let {dogImage.loadImage(dog.imageUrl, getProgressDrawable(it))}
            }
        })
    }
}

这是 DetailViewModel。

class DetailViewModel(application: Application): BaseViewModel(application) {
    val dogLiveData = MutableLiveData<DogBreed>()

    fun fetch(uuid: Int){
        launch {
            val dog = DogDatabase(getApplication()).dogDao().getDog(uuid)
            dogLiveData.value = dog
        }
    }
}

这是我对协程的实现。

abstract class BaseViewModel(application: Application): AndroidViewModel(application), CoroutineScope {

    private val job = Job()

    override val coroutineContext: CoroutineContext
        get() = job + Dispatchers.Main

    override fun onCleared() {
        super.onCleared()
        job.cancel()
    }
}

observerViewModel() 中的 Observer 似乎从未被调用过。为什么?

【问题讨论】:

  • 不要认为这是导致此问题的原因,但通常应使用viewLifecycleOwner 而不是this 调用observe()
  • 我试过了,但没用。
  • 你确认dogLiveData.value = dog被调用了吗?
  • fwiw 我在这里运行或多或少相同的代码,它工作。
  • @JohnO'Reilly 难道是我搞砸了别的东西?也许是协程?我将添加我的 BaseViewModel 实现。

标签: android kotlin mvvm android-livedata android-jetpack


【解决方案1】:

你能确认一下线路吗

dogLiveData.value = dog

正在使用断点调用?

尝试调用

viewModel.fetch(dogUuid)

之后

observeViewModel()

【讨论】:

  • 我已经做到了。不幸的是,没有工作。日志似乎没有错误,我也尝试过冷启动和重建。
【解决方案2】:

viewModel.fetch(dogUuid)之前添加observeViewModel()

class DetailFragment : Fragment() {

    private var dogUuid = 0
    private lateinit var viewModel: DetailViewModel

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        arguments?.let {
            dogUuid = DetailFragmentArgs.fromBundle(it).dogUuid
        }

        viewModel = ViewModelProviders.of(this).get(DetailViewModel::class.java)

 observeViewModel()

 viewModel.fetch(dogUuid)


    }

    private fun observeViewModel(){
        viewModel.dogLiveData.observe(this, Observer{ dog ->
            dog?.let {
                dogName.text = dog.dogBreed
                dogPurpose.text = dog.bredFor
                dogTemperament.text = dog.temperament
                dogLifespan.text = dog.lifeSpan
                context?.let {dogImage.loadImage(dog.imageUrl, getProgressDrawable(it))}
            }
        })
    }
}

【讨论】:

    【解决方案3】:

    问题是我忘记将参数uuid 传递给DetailFragment,导致dog 对象在DetailViewModel.fetch(uuid) 中为空。因此,上面的代码是正确的,问题出在其他地方。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多