【问题标题】:How to Return LiveData from Repository如何从存储库返回 LiveData
【发布时间】:2020-05-09 11:05:28
【问题描述】:

我只是看不到如何将 LiveData 从 Repo 链接到 VM,因此我试图将其归结为最简单的示例!:

片段

class LoginFragment : Fragment() {

private lateinit var loginViewModel: LoginViewModel
private var mCurrentName = "Blank!"

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                          savedInstanceState: Bundle?): View? {
    // Inflate the layout for this fragment
    val binding: LoginFragmentBinding = DataBindingUtil.inflate(
        inflater, R.layout.login_fragment, container, false)

    binding.apply {
        loginButton.setOnClickListener{
            loginViewModel.changeText()
        }
    }
    return binding.root
}


override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    loginViewModel = ViewModelProviders.of(this).get(LoginViewModel::class.java)

    loginViewModel.getCurrentName().observe(viewLifecycleOwner, Observer {
        mCurrentName = it      // I'm expecting mCurrentName to equal "Button Clicked!" when button clicked..
        makeToast()     // Toast works, but variable remains unchanged..
    })

}

private fun makeToast() {
    Toast.makeText(activity, mCurrentName, Toast.LENGTH_LONG).show()
}

视图模型

class LoginViewModel : ViewModel() {

private val firestoreRepository : FirestoreRepository = FirestoreRepository()
private var mCurrentName = MutableLiveData<String>()

fun changeText(){
    mCurrentName = firestoreRepository.changeText()
}

存储库

class FirestoreRepository {

    private val mCurrentName = MutableLiveData<String>()

    fun changeText(): MutableLiveData<String> {
            mCurrentName.value = "Button Clicked!!"
            return mCurrentName
    }

我假设我误解了观察者功能的工作原理..

【问题讨论】:

    标签: android kotlin mvvm repository android-livedata


    【解决方案1】:

    实际上,如果您在存储库中维护LiveData,我认为ViewModel 中也不需要单独的LiveData。您只需从活动中观察一次 LiveData。然后直接对存储库实例进行任何更改。所以如果我必须在你的代码中显示它,它可能看起来像这样。

    1. Activity 类:将 makeToast 方法更改为 observeCurrentName(),如下所示:

      private fun observeCurrentName() {
          vm.getCurrentName().observe(this, Observer{ 
              //Toast here 
          })
      }
      
    2. 你的虚拟机:

      class LoginViewModel : ViewModel() {
          ...
      
          fun getCurrentName(): MutableLiveData<String>{
              return repository.getCurrentName()
          }
      
          fun setCurrentName(name: String?){
              repository.setCurrentName(name)
          }
      
          ...
      }
      
    3. 您的存储库:

      class FirestoreRepository {
      
          private val mCurrentName = MutableLiveData<String>()
      
          fun getCurrentName(): MutableLiveData<String>{
              return mCurrentName
          }
      
          fun setCurrentName(name: String?){
              mCurrentName.value = name //This will trigger observer in Activity
          }
      }
      

    【讨论】:

    • 谢谢你,Sandesh - 这个解释正是我想要的。我已经实施并且效果很好。我相信根据我的研究,在 onActivityCreated 中创建观察者的正确位置如图所示 - 如果他们不同意,希望有人可以发表评论?
    【解决方案2】:

    无需在ViewModel 中更改MutableLiveData。尝试将Repository 发送给View 的任何内容传递给View。检查下面

    class LoginViewModel : ViewModel() {
    
        private val firestoreRepository : FirestoreRepository = FirestoreRepository()
    
        fun getCurrentName(): MutableLiveData<String> {
            return firestoreRepository.getCurrentName()
        }
    
        fun changeText() {
            firestoreRepository.changeText()
        }
    }
    

    还有你的FirestoreRepository

    class FirestoreRepository {
    
        private val mCurrentName = MutableLiveData<String>()
    
        fun getCurrentName(): MutableLiveData<String> {
            return mCurrentName
        }
    
        fun changeText() {
            mCurrentName.value = "Button Clicked!!"
        }
    }
    

    【讨论】:

    • 这与上面的解释基本相同,但方式不同,所以我赞成 - 谢谢!
    【解决方案3】:

    在您开始观察 mCurrentName(LiveData 变量本身而不是它的内容)之后,您正在更改它。指导似乎是不要在 Repository 层使用LiveData(例如使用 Coroutines/Flow)....但是现在你可以有类似以下的东西(或者可能使用 LiveData 转换之一)

    private val mCurrentName = firestoreRepository.currentName()
    
    fun changeText(){
        firestoreRepository.changeText()
    }
    

    【讨论】:

      猜你喜欢
      • 2017-12-26
      • 1970-01-01
      • 2020-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-02
      • 2020-03-16
      • 2019-02-04
      相关资源
      最近更新 更多