Compose State的各种转换

普通值 转换为 State

很简单,就一个方法

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 转换为 MutableState

/**
 * 将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)

StateFlow 转换为 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, 但其为不可变的

SharedPreferences之类的 转换为 MutableState



/**
 * 将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

MutableState 转换为 Flow 很简单,因为系统提供了相应的api

        var text by rememberMutableStateOf("")
        val flow = snapshotFlow {
            text
        }

这样每次 text 状态的改变,都会引起 flow 的回调

ps:响应的是监听的lambda的返回值

end

对Kotlin或KMP感兴趣的同学可以进Q群 101786950

如果这篇文章对您有帮助的话

可以扫码请我喝瓶饮料或咖啡(如果对什么比较感兴趣可以在备注里写出来)

相关推荐

  1. 计算机各种转换

    2023-12-26 23:48:01       11 阅读
  2. vue各种时间类型转换

    2023-12-26 23:48:01       12 阅读
  3. 各个类型和Json类型相互转换

    2023-12-26 23:48:01       23 阅读
  4. css各种样式

    2023-12-26 23:48:01       15 阅读

最近更新

  1. vue配置sql规则

    2023-12-26 23:48:01       0 阅读
  2. ios 企业签名证书购买_iOS苹果企业签名须知

    2023-12-26 23:48:01       0 阅读
  3. android 使用系统工具bootchart统计开机时长

    2023-12-26 23:48:01       0 阅读
  4. 【工具分享】FOFA——网络空间测绘搜索引擎

    2023-12-26 23:48:01       0 阅读
  5. 物联网应用,了解一点 WWAN全球网络标准

    2023-12-26 23:48:01       0 阅读
  6. Jupyter Notebook详尽安装教程

    2023-12-26 23:48:01       1 阅读
  7. 实现淘客返利系统中的用户登录与权限管理

    2023-12-26 23:48:01       1 阅读

热门阅读

  1. python初试四

    2023-12-26 23:48:01       43 阅读
  2. 单体项目-动态上下文问题

    2023-12-26 23:48:01       35 阅读
  3. React入门介绍

    2023-12-26 23:48:01       44 阅读
  4. python异常之try/finally分句

    2023-12-26 23:48:01       32 阅读
  5. 2023年大模型回顾

    2023-12-26 23:48:01       29 阅读
  6. orangepi——基于官方外设开发

    2023-12-26 23:48:01       39 阅读
  7. vue打包dist在iphone跨域问题

    2023-12-26 23:48:01       31 阅读
  8. henauOJ 1098: 数字统计

    2023-12-26 23:48:01       32 阅读
  9. K8S从harbor中拉取镜像的规则imagePullPolicy

    2023-12-26 23:48:01       26 阅读