android - Android开发中如何正确处理View State
问题描述
目前我在我的应用程序中有这种方法:
ViewState(每个屏幕一个 viewState)
sealed class CategoriesViewState {
object Loading : CategoriesViewState()
data class Error(
val errorMessage: String,
val messageType: UIComponentType
) : CategoriesViewState()
data class CategoryList(
val categories: List<Category>
) : CategoriesViewState()
}
我使用实时数据在我的片段/活动中观察到这种状态:
viewModel.viewState.observe(viewLifecycleOwner, Observer {
when (it) {
is CategoriesViewState.Loading -> {
progress_bar.visibility = View.VISIBLE
Log.d(TAG, "LOADING")
}
is CategoriesViewState.Error -> {
progress_bar.visibility = View.GONE
Log.d(TAG, "ERROR")
}
is CategoriesViewState.CategoryList -> {
progress_bar.visibility = View.GONE
Log.d(TAG, "DATA")
}
}
})
它工作正常。
但在我看来,随着应用程序的增长,它的效率很低。
假设我的应用程序中有 20 个屏幕:我需要 20 个视图状态,我需要在每个屏幕中编写相同的 when 语句,我需要在每个屏幕中编写这个丑陋的 Visible/Gone(更不用说我需要在每次通话中设置加载状态)
也许我完全错了,这是常见的方法,但对我来说,这似乎是很多代码重复。
我没有具体问题,我只想知道这是否是 Android 开发中的常用方法,如果不是,我在代码中做错了什么?
解决方案
关于不同活动的状态,您无需每次制作新屏幕时都进行此操作。您可以按照以下方法进行相应修改:
sealed class UIState<out T> where T : Any? {
object Loading : UIState<Nothing>()
data class Success<T>(val data: T) : UIState<T>()
data class Failure(val errorMessage: String, val messageType: UIComponentType) : UIState<Nothing>()
}
所以,现在你CategoriesViewState
可以表示为UiState<List<Category>>
。
我还创建了一些扩展函数以使观察更容易:
infix fun <T> UIState<T>.takeIfSuccess(onSuccess: UIState.Success<T>.() -> Unit): UIState<T> {
return when (this) {
is UIState.Success -> {
onSuccess(this)
this
}
else -> {
this
}
}
}
infix fun <T> UIState<T>.takeIfError(onError: UIState.Failure.() -> Unit): UIState<T> {
return when (this) {
is UIState.Failure -> {
onError(this)
this
}
else -> {
this
}
}
}
在观察实时数据的方法中:
viewModel.viewState.observe(viewLifecycleOwner) { state ->
state takeIfSuccess {
// Here's the success state
} takeIfError {
// Here's the error state
}
}
推荐阅读
- windows-subsystem-for-linux - WSL2 无法通过 Windows 访问,但可以通过终端正常工作
- django - nginx - gunicorn - django allauth 重定向到 127.0.0.1 问题,我该如何解决?
- javascript - Bootstrap 5 Accordion - 从不同页面访问时滚动到右侧选项卡
- c++ - 线程安全数组计数器 C++
- flutter - Flutter 无法在 ListTile 上显示 JSON 图像
- python - 如何改进此电子邮件提取正则表达式?
- reactjs - 如何为 React 切换自定义钩子设置默认状态?
- calculated-field - 有没有办法在 tableau 中解析一个字符串以获得可变长度的字符串?
- c++ - C++ 动态数组访问冲突,读写位置
- angular - Angular 12 路由问题与路径中的斜线