【问题标题】:LiveData.getValue() is not null but LiveData.observe is nullLiveData.getValue() 不为空,但 LiveData.observe 为空
【发布时间】:2020-08-02 11:56:59
【问题描述】:

我的代码有一个奇怪的问题。

场景...我有一个数据列表,我在 Viewmodel 中检索它们并从 Fragment 观察。当我第一次打开我的 Fragment 时,一切正常。但是当我从另一个片段返回时,LiveData 不为空。所以我这样检查,

if(liveData.getUser().getValue()!= null){

//here getName() does not null and I get the value from liveData      

println(liveData.getUser().getName()) //this work
 
 liveData.getUser().observe(lifeCycleOwner(),
 Observer { user: User? ->{
  //Here LiveData is null
       }
     })

 }
 else{
         liveData.initiate()
         LiveData.getUser.observe(//same as above)
    }

我在 onViewCreated() 中观察。我不知道为什么 LiveData.getValue() 不为 null 但 LiveData.observe 返回 null。

有人可以帮我解决这个问题吗?

编辑...这是我的UserViewmodel.class

 class UserViewModel : ViewModel(){
       private var userLiveData : LiveData<User>?= MutableLiveData<>()
      fun initiate (){
          userLiveData = UserRepository.getUserData()
      }
      fun getUser() : LiveData<User>{
        Log.e("get called")
        return userLiveData
       }
 }

编辑 2 这是我的 UserRepository.class

 class UserRepository {
     private var userData : MutableLiveData<User>?= null
     fun getUserData(): LiveData<User>{
          retrieveUser()
          return userData
     }
     fun retrieveUser (){
          val names = arrayOf("user1","user2","user3","user4","user5")
        for(name :String in names){
             user = User()
             user.setName(name)
             userData.value = user
          }
      }
 }

【问题讨论】:

  • 在这里发布视图模型
  • 我已添加,请再次查看。
  • 你不需要在if else观察,一次就可以了,顺便说一下UserRepository
  • 我已添加先生。如果我不使用 if else ,则从另一个 Fragment 返回会使最后一次观察到的值调用两次。即最后观察到的值在返回时加倍。

标签: android kotlin android-livedata android-architecture-components


【解决方案1】:

输出

I/System.out: user1
I/System.out: user2
I/System.out: user3
I/System.out: user4
I/System.out: user5

简化的干净代码
注:阅读code cmets了解

查看(片段或活动)

val userViewModel: UserViewModel = ViewModelProvider(this).get(UserViewModel::class.java)
    userViewModel.getUser().observe(this, Observer {
        for (user in it) {
            println(user.name)
        }
    })

视图模型

class UserViewModel : ViewModel(){
private var userRepository = UserRepository()
private var userLiveData = MutableLiveData<ArrayList<User>>()

//init block where initialise happens
init {
    //retrieve users and set in user live data
    userLiveData.postValue(userRepository.retrieveUsers())
}
fun getUser() : MutableLiveData<ArrayList<User>> {
    //observe user live date in view
    return userLiveData
}

override fun onCleared() {
    super.onCleared()
    //clear live data
    userLiveData.postValue(null)
}
}

存储库

class UserRepository {
/**
 * retrieve users as ArrayList
 */
fun retrieveUsers (): ArrayList<User> {
    val names = arrayOf("user1","user2","user3","user4","user5")
    val list = ArrayList<User>()
    for(name :String in names){
        val user = User()
        user.name = name
        list.add(user)
    }
    return list
}
}

【讨论】:

  • 但是当我从另一个 Fragment 回来时,最后观察到的值会被观察两次。所以输出就像user5, user1, user2, user3, user4, user5。旧的最后观察值首先被观察,然后其他值被观察。并且 onCleared() 永远不会被调用。我使用的是 BottomNavigationView 和 Viewpager。我无法检索 ArrayList,因为房间中的数据一个接一个地被检索。提供的存储库是示例。
  • 我该如何实现这个?我不知道如何在下次观察之前清除上次观察到的数据。
猜你喜欢
  • 2020-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多