片段中的观察者有效,但活动中无效

时间:2020-01-24 14:21:20

标签: android android-livedata observers lifecycleowner

我在一个片段中创建了一个观察器,该观察器工作正常(当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")
    })
}

活动(当我将观察者放到活动中时,它不是!):

    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()  }

回购(从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有关,但我很茫然!

1 个答案:

答案 0 :(得分:2)

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

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