很简单,就一个方法
val stringState = mutableStateOf("value")
但是也得注意,上面的方法是针对泛型的,如果只是基本数据类型,推荐使用相应的方法,在JVM上可以减少拆装箱带来的消耗
val intState = mutableIntStateOf(0)
State常用的几种使用方法
1.使用 MutableState 的对象,通过控制 MutableState 对象的 value 属性来获取和设置值
val state1 = remember { mutableStateOf("") }
TextField(state1.value, { state1.value = it })
?2.使用 MutableState 的解构声明,获取 value 和 setValue(高阶函数) 来使用
val (value, setValue) = remember { mutableStateOf("") }
TextField(value, setValue)
?
可以看到其声明,value 和 setValue 就对应 component1 和 component2 方法
3.使用属性代理
var state3 by remember { mutableStateOf("") }
TextField(state3, { state3 = it })
使用了 by 关键字,?这样?MutableState 对象的 getter 和 setter 就会被代理了,具体实现如下:?
/**
* 将liveData放在compose中使用
* ps:由于MutableLiveData是使用java写的,所以没有非空初始值的一定要声明为可空类型
*/
@Composable
fun <T : Any> MutableLiveData<T>.toMutableState(): MutableState<T> {
val state = observeAsState() as State<T>
return remember { MutableStateFromMutableLiveData(this, state) }
}
/**
* creator: lt lt.dygzs@qq.com
* effect : 将[state]转换成[MutableState],[MutableState.value]的set会传递给[mutableLiveData]
* warning:
*/
class MutableStateFromMutableLiveData<T : Any>(
private val mutableLiveData: MutableLiveData<T>,
private val state: State<T>
) :
MutableState<T> {
override var value: T
get() = state.value
set(value) {
mutableLiveData.value = value
}
override fun component1(): T = value
override fun component2(): (T) -> Unit = { value = it }
}
可以看到,我们创建了一个?MutableState 的子类?MutableStateFromMutableLiveData, 然后通过LiveData提供的api将其转为了State(不能修改的), 然后我们再监听?MutableStateFromMutableLiveData 的 value 的 setter 来修改 LiveData, 然后修改了 LiveData 的值后又会响应 State 的 value 的修改(其实也可以完全自定义实现?MutableState)
和LiveData类似
/**
* 将stateFlow放在compose中使用
*/
@Composable
fun <T> MutableStateFlow<T>.toMutableState(): MutableState<T> {
val state = collectAsState()
return remember { MutableStateFromMutableStateFlow(this, state) }
}
/**
* creator: lt lt.dygzs@qq.com
* effect : 将[state]转换成[MutableState],[MutableState.value]的set会传递给[mutableStateFlow]
* warning:
*/
class MutableStateFromMutableStateFlow<T>(
private val mutableStateFlow: MutableStateFlow<T>,
private val state: State<T>
) : MutableState<T> {
override var value: T
get() = state.value
set(value) {
mutableStateFlow.value = value
}
override fun component1(): T = value
override fun component2(): (T) -> Unit = { value = it }
}
当然 Flow 也能转为 State, 但其为不可变的
/**
* 将sp转为state,对state的操作会映射到对sp的操作
*/
@Composable
fun <T : Any> SpKey<T>.toMutableState(): MutableState<T> {
return remember(this) {
MutableStateFromSp(this)
}
}
/**
* creator: lt 2022/10/7 lt.dygzs@qq.com
* effect : 将[state]转换成[MutableState],[MutableState.value]的set会传递给[mutableStateFlow]
* warning:
*/
class MutableStateFromSp<T : Any>(
private val sp: SpKey<T>,
) : MutableState<T> {
override var value: T
get() = sp.read()
set(value) {
field = value
sp.write(value)
}
override fun component1(): T = value
override fun component2(): (T) -> Unit = { value = it }
}
代码其实和上面的差不多,每次读取都会从 sp 中读取,而写入会同时写入到 sp 中(也可以自行添加缓存实现)
此代码不止可以用在 sp 上?
MutableState 转换为 Flow 很简单,因为系统提供了相应的api
var text by rememberMutableStateOf("")
val flow = snapshotFlow {
text
}
这样每次 text 状态的改变,都会引起 flow 的回调
ps:响应的是监听的lambda的返回值
end
对Kotlin或KMP感兴趣的同学可以进Q群?101786950
如果这篇文章对您有帮助的话
可以扫码请我喝瓶饮料或咖啡(如果对什么比较感兴趣可以在备注里写出来)