Compose State的各种转换

14 篇文章 0 订阅
13 篇文章 0 订阅

普通值 转换为 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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值