我已经用 View 模型装配了一个简单的登录 fragment 。 这是 fragment :
class LoginFragment : Fragment() {
companion object {
fun newInstance() = LoginFragment()
}
private lateinit var viewModel: LoginViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.login_fragment, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProviders.of(this).get(LoginViewModel::class.java)
viewModel.loginState.observe(this, Observer{
handleState(it)
})
login_button.setOnClickListener {
viewModel.isUserValid(username.text.toString(), pass.toString())
}
}
private fun handleState(status: RegisterState) {
if (status.statusMessage.equals("Good"))
view?.findNavController()?.navigate(R.id.action_registerFragment_to_homeFragment)
else
Snackbar.make(login_container, "Welcome to SwA", Snackbar.LENGTH_LONG).show();
}
}
这是我的 View 模型:
class LoginViewModel : ViewModel() {
lateinit var auth: FirebaseAuth
private var _loginState = MutableLiveData<LoginState>()
val loginState : MutableLiveData<LoginState> get() = _loginState
init {
loginState.value = LoginState()
}
fun isUserValid(email: String, password: String): Boolean {
//Add call to authenticate through firebase
auth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener {
if (it.isSuccessful) {
// Sign in success, update UI with the signed-in user's information
val user = auth.currentUser
//updateUI(user)
} else {
// If sign in fails, display a message to the user.
_loginState.value?.statusMessage = "Authentication Failed"
}
}
return true
}
}
当尝试登录失败时,它会工作并注册对字符串状态的更改,但是它还会在加载 fragment 时提交 onChange() ,导致在 fragment 实际输入任何内容之前, snackbar 就出现在 UI 中被 build 。如何在不触发 onChange() 的情况下初始化 View 状态?
最佳答案
LiveData 类有一个方法
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
它检查 LifeCycle
、Activity
或 Fragment
的所有者是否处于 STARTED 后的状态,这意味着对于 Activity 来说,如果它具有调用了onStart()
。
因此,每当 Activity
或 Fragment
观察 LiveData 时,它都会在 onStart 之后通过 setValue
或 PostValue
获取 LiveData 的值被调用。
防止相同值多次更新 UI 的方法之一是使用 SingleLiveEvent
类,例如 here 。另一种是使用 Event类,例如here .
关于android - 可变实时数据值在创建 fragment 时更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57734738/