观察者不会在 LiveData 更改时被调用
Observer is not called on LiveData change
我有一个狗的列表,当我点击列表中的特定狗时,我可以看到详细信息。但是,出于某种原因,文本视图(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()
}
}
似乎从未调用过 observeViewModel() 中的 Observer。为什么?
你能确认线路吗
dogLiveData.value = dog
正在用断点调用吗?
试试打电话
viewModel.fetch(dogUuid)
之后
observeViewModel()
在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))}
}
})
}
}
问题是我忘记将参数 uuid
传递给 DetailFragment
,这导致 dog
对象在 DetailViewModel.fetch(uuid)
中为 null。因此,上面的代码是正确的,问题出在其他地方。
我有一个狗的列表,当我点击列表中的特定狗时,我可以看到详细信息。但是,出于某种原因,文本视图(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()
}
}
似乎从未调用过 observeViewModel() 中的 Observer。为什么?
你能确认线路吗
dogLiveData.value = dog
正在用断点调用吗?
试试打电话
viewModel.fetch(dogUuid)
之后
observeViewModel()
在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))}
}
})
}
}
问题是我忘记将参数 uuid
传递给 DetailFragment
,这导致 dog
对象在 DetailViewModel.fetch(uuid)
中为 null。因此,上面的代码是正确的,问题出在其他地方。