Android中StateFlow的简单使用
·
前言:
最近在学习StateFlow,感觉很神奇,于是记录了一下.
1.简介:
StateFlow 是一个状态容器式可观察数据流,可以向其收集器发出当前状态更新和新状态更新。还可通过其 value 属性读取当前状态值。如需更新状态并将其发送到数据流,请为 MutableStateFlow 类的 value 属性分配一个新值。
2.实际使用:
@ExperimentalCoroutinesApi
class MainViewModel :ViewModel(){
private val _loginUiState = MutableStateFlow<LoginUiState>(LoginUiState.Empty)
val loginUiState: StateFlow<LoginUiState> = _loginUiState
fun login(username: String, password: String) = viewModelScope.launch {
_loginUiState.value = LoginUiState.Loading
delay(2000L)
if(username == "android" && password == "123456") {
_loginUiState.value = LoginUiState.Success
} else {
_loginUiState.value = LoginUiState.Error("Wrong credentials")
}
}
sealed class LoginUiState {
object Success : LoginUiState()
data class Error(val message: String) : LoginUiState()
object Loading : LoginUiState()
object Empty : LoginUiState()
}
}
3.MainActivity中代码:
@ExperimentalCoroutinesApi
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.btnLogin.setOnClickListener {
viewModel.login(
binding.etUsername.text.toString(),
binding.etPassword.text.toString()
)
}
lifecycleScope.launchWhenStarted {
viewModel.loginUiState.collect {
when (it) {
is MainViewModel.LoginUiState.Success -> {
Snackbar.make(
binding.root,
"Successfully logged in",
Snackbar.LENGTH_LONG
).show()
binding.progressBar.isVisible = false
}
is MainViewModel.LoginUiState.Error -> {
Snackbar.make(
binding.root,
it.message,
Snackbar.LENGTH_LONG
).show()
binding.progressBar.isVisible = false
}
is MainViewModel.LoginUiState.Loading -> {
binding.progressBar.isVisible = true
}
else -> Unit
}
}
}
}
override fun onDestroy() {
super.onDestroy()
}
}
4.和Flow、LiveData联系,官网解释如下:
StateFlow、Flow 和 LiveData
StateFlow 和 LiveData 具有相似之处。两者都是可观察的数据容器类,并且在应用架构中使用时,两者都遵循相似模式。
但请注意,StateFlow 和 LiveData 的行为确实有所不同:
-
StateFlow需要将初始状态传递给构造函数,而LiveData不需要。 -
当 View 进入
STOPPED状态时,LiveData.observe()会自动取消注册使用方,而从StateFlow或任何其他数据流收集数据的操作并不会自动停止。如需实现相同的行为,您需要从Lifecycle.repeatOnLifecycle块收集数据流。
5.实现的效果图如下:

![]()

更多推荐



所有评论(0)