【问题标题】:Observer in Fragment works but not in ActivityFragment 中的观察者有效,但在 Activity 中无效
【发布时间】:2020-05-10 21:22:23
【问题描述】:

我在 Fragment 中创建了一个完美运行的观察者(当 Int 增加时它会触发祝酒词),但是当我尝试将此代码移动到 Activity 中时,观察者似乎没有连接,并且它不会更新LiveData 发生变化。

片段(这行得通!):

    override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)

    loginViewModel = ViewModelProviders.of(this).get(LoginViewModel::class.java)

    loginViewModel.getLoginAttemptCount().observe(this, Observer { count ->
        if (count > 0) makeToast("Authentication failed")
    })
}

Activity(当我将观察者放入 Activity 时它没有!):

    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.login_activity)

    loginViewModel = ViewModelProviders.of(this).get(LoginViewModel::class.java)

    loginViewModel.getLoginAttemptCount().observe(this, Observer { count ->
        if (count > 0) makeToast("Authentication failed")
    })
}

ViewModel(在 VM 中都调用相同的函数):

    fun getLoginAttemptCount(): MutableLiveData<Int> {
    Log.d(TAG, "getLoginAttemptCount()")
    return firestoreRepository.getLoginAttemptCount()  }

Repo(从 VM 调用):

        fun getLoginAttemptCount(): MutableLiveData<Int>{
            Log.d(TAG, "getLoginAttemptCount()")
            return loginAttempt
    }

每次登录尝试时,loginAttempt.value 都会增加,我已经验证了这在 Logcat 中有效..

关于信息,makeToast 只是一个创建合理 Toast(文本和位置)的函数:

private fun makeToast(message: String) {

    val centeredText: Spannable = SpannableString(message)
    centeredText.setSpan(
        AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER),
        0, message.length - 1,
        Spannable.SPAN_INCLUSIVE_INCLUSIVE
    )

    val toast = Toast.makeText(this, centeredText, Toast.LENGTH_LONG)
    toast.setGravity(Gravity.CENTER,0,0)
    toast.show()
    Log.d(TAG, "Toast message: $message")
}

我假设它与 lifeCycleOwner 有关,但我不知所措!

【问题讨论】:

  • 您是否尝试过手动将一些数据发布到您的活动内的AttemptCount 以查看它是否被触发?
  • 我正在记录流程的每个部分,并且存储库中的 LiveData 正在更改 - 创建 Activity 时观察者只是没有连接到 LiveData(正如我所说,它可以正常工作片段中的代码)..

标签: android android-livedata observers lifecycleowner


【解决方案1】:

loginViewModel = ViewModelProviders.of(this).get(LoginViewModel::class.java)

在片段中 您正在使用上面的行创建将片段的上下文传递给 viewmodel 的 loginviewmodel 所以,android 做的第一件事就是检查,如果它包含与这个片段关联的任何其他视图模型,如果它包含它将不会创建新的视图模型,它将返回旧的 如果它不包含它,则创建一个新的。Viewmodel 是使用键值对创建的。 所以在你的情况下 您正在为片段和活动创建总共两个视图模型您正在更改片段的实时数据,但您正在尝试使用活动视图模型在活动中观察它。 如果您想实现需要在活动和片段之间创建共享视图模型。How to create shared viewmodel

【讨论】:

  • 非常感谢 Roshan。在研究共享视图模型时,还发现了以下博客文章,其中包含一些帮助我理解的代码:medium.com/mindorks/…
猜你喜欢
  • 2013-01-31
  • 2021-04-09
  • 1970-01-01
  • 1970-01-01
  • 2021-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多