Jetpact Compose 状态管理简单理解,android 设计模式的应用场景
var data = remember {
mutableStateOf("")
}
注:mutableStateOf 必须使用 remember 嵌套才能在数据更改的时候重组界面
rememberSaveable 保存配置
remember
可以帮助我们在界面重组的时候保存状态,而rememberSaveable
可以帮助我们存储配置更改(重新创建activity或进程
)时的状态。
Livedata、Flow、RxJava 转换为状态
这三个框架是安卓常用的三个响应式开发框架,都支持转化为State
对象,以 Flow 举例,如下代码可以转化为一个 State:
val favorites = MutableStateFlow<Set<String>>(setOf())
val state = favorites.collectAsState()
有状态和无状态
使用 remember、rememberSaveState 方法保存状态的组合项是有状态组合
反之是无状态组合
状态提升
如下代码是官方关于状态提升的代码:
本例代码中 HelloContent 是无状态的,它的状态被提升到了 HelloScreen 中,HelloContent 有name
和onNameChange
两个参数,name 是状态,通过 HelloScreen 组合项传给 HelloContent
而 HelloContent 中发生的更改它也不能自己进行处理,必须将更改传给HelloScreen
进行处理并重组界面。
以上的逻辑叫做:状态下降,事件上升
@Composable
fun HelloScreen() {
var name by rememberSaveable { mutableStateOf("") }
HelloContent(name = name, onNameChange = { name = it })
}
@Composable
fun HelloContent(name: String, onNameChange: (String) -> Unit) {
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = "Hello, $name",
modifier = Modifier.padding(bottom = 8.dp),
style = MaterialTheme.typography.h5
)
OutlinedTextField(
value = name,
onValueChange = onNameChange,
label = { Text("Name") }
)
}
}
前面的介绍中我们知道使用rememberSaveable
方法我们可以通过 Bundle 的方式保存状态,那么如果我们要保存的状态不方便用 Bundle 的情况下该何如处理呢?
以下三种方式,可以实现对非 Bundle 的数据的保存(配置更改后的保存)
Parcelize
代码示例:
@Parcelize
data class City(val name: String, val country: String) : Parcelable
@Composable
fun CityScreen() {
var selectedCity = rememberSaveable {
mutableStateOf(City("Madrid", "Spain"))
}
}
MapSaver
data class City(val name: String, val country: String)
val CitySaver = run {
val nameKey = "Name"
val countryKey = "Country"
mapSaver(
save = { mapOf(nameKey to it.name, countryKey to it.country) },
restore = { City(it[nameKey] as String, it[countryKey] as String) }
)
}
@Composable
fun CityScreen() {
var selectedCity = rememberSaveable(stateSaver = CitySaver) {
mutableStateOf(City("Madrid", "Spain"))
}
}
ListSaver
data class City(val name: String, val country: String)
val CitySaver = listSaver<City, Any>(
save = { listOf(it.name, it.country) },//数组中保存的值和 City 中的属性是顺序对应的
restore = { City(it[0] as String, it[1] as String) }
)
@Composable
fun CityScreen() {
var selectedCity = rememberSaveable(stateSaver = CityS
aver) {
mutableStateOf(City("Madrid", "Spain"))
}
}
评论