Observer 在 Fragment 中有效但在 Activity 中无效

Observer in Fragment works but not in Activity

我在 Fragment 中创建了一个完美运行的 Observer(当 Int 增加时它会触发 toast),但是当我尝试将此代码移入 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 有关,但我不知所措!

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

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

之间创建共享视图模型