我在一个片段中创建了一个观察器,该观察器工作正常(当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有关,但我很茫然!
答案 0 :(得分:2)
loginViewModel = ViewModelProviders.of(this).get(LoginViewModel :: class.java)
在片段中 您正在使用上面的代码创建将片段上下文传递给viewmodel的loginviewmodel 因此,android做的第一件事是检查它是否包含与此片段关联的其他任何视图模型,如果包含则不创建新的视图模型,它将返回旧的视图模型 如果不包含它,则创建一个新的ViewView使用键值对创建。 所以你的情况 您正在创建每个片段和活动的总共两个视图模型,您正在更改片段的实时数据,但是您尝试使用活动视图模型在活动中观察它。 如果您想实现这一点,则需要在活动和片段之间创建共享的视图模型。How to create shared viewmodel