可变实时数据值在创建片段时更新
Mutable Live Data Value is updated on creation of 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();
}
}
这是我的视图模型:
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
}
}
这有效并在尝试登录失败时注册对字符串状态的更改,但是它还会在加载片段时提交 onChange() 导致小吃店出现在 UI 之前在创建片段时实际上输入了任何内容。如何在不触发 onChange() 的情况下初始化视图状态?
LiveData class 有一个方法
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
检查 LifeCycle
、Activity
或 Fragment
的所有者是否处于 STARTED 之后的状态,这意味着 Activity 如果它调用了 onStart()
.
因此,每当 Activity
或 Fragment
观察到 LiveData 时,它会在调用 onStart 后通过 setValue
或 PostValue
获取 LiveData 的值。
防止同一值多次更新 UI 的方法之一是使用 SingleLiveEvent
class,例如 here. Another one is using Event class, example is .
我用视图模型装配了一个简单的登录片段。 这是片段:
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();
}
}
这是我的视图模型:
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
}
}
这有效并在尝试登录失败时注册对字符串状态的更改,但是它还会在加载片段时提交 onChange() 导致小吃店出现在 UI 之前在创建片段时实际上输入了任何内容。如何在不触发 onChange() 的情况下初始化视图状态?
LiveData class 有一个方法
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
检查 LifeCycle
、Activity
或 Fragment
的所有者是否处于 STARTED 之后的状态,这意味着 Activity 如果它调用了 onStart()
.
因此,每当 Activity
或 Fragment
观察到 LiveData 时,它会在调用 onStart 后通过 setValue
或 PostValue
获取 LiveData 的值。
防止同一值多次更新 UI 的方法之一是使用 SingleLiveEvent
class,例如 here. Another one is using Event class, example is