Compose系列 三 状态管理

本系列是我学习compose过程中,对官方文档的翻译和解读,以及实验性的Demo工程。主要参考官方文档和中文手册

全部的正文内容(Demo工程除外)源自Compose官方文档,个人解读以引用的形式插入。

Compose 官方文档 https://developer.android.google.cn/jetpack/compose

Compose 中文手册 https://compose.net.cn/

本文翻译内容 https://developer.android.google.cn/jetpack/compose/state

App中的状态是指任何可以随着时间改变的值。这是个非常宽泛的概念,包含了几乎所有东西,大到一个Room数据库,小到某个类的一个成员变量

所有的Android应用都是在把状态展示给用户。下面是一些例子

  • 无网络连接时展示的snackBar
  • A blog post and associated comments.
  • 用户点击按钮时触发的涟漪动画
  • 用户在图像上绘制的贴纸

Jetpack Compose 能帮助你明确在哪里存放这些状态,以及如何使用它们。本文主要关心状态与可组合函数之间的关系,以及Jetpack Compose提供了一些帮助你管理状态的API。

状态与绘制

Compose是声明式的,所以想更改一个组件的状态,只能用新的状态值去调用该组件的可组合函数。这些状态值描述了这个UI组件的状态。状态的更新就对应着重绘的发生。所以,当UI的状态值改变时,基于XML的UI框架会自动刷新UI,但是在Compose中,必须显式地调用该UI的可组合函数,才能刷新该UI

@Composable
fun HelloContent() {
   
   Column(modifier = Modifier.padding(16.dp)) {
   
       Text(
           text = "Hello!",
           modifier = Modifier.padding(bottom = 8.dp),
           style = MaterialTheme.typography.h5
       )
       OutlinedTextField(
           value = "",
           onValueChange = {
    },
           label = {
    Text("Name") }
       )
   }
}

运行上述代码,会发现虽然向输入框输入了文字,但并没有渲染出来。这是因为Compose的渲染机制决定,必需显式重新调用OutlinedTextField这个可组合函数,但显然这里并没有

这里的OutlinedTextField暂时理解成Compose版本的EditText

关键词解释:

Composition: Jetpack Compose把可组合函数渲染成UI的这个过程,可以意译成绘制

Initial composition: 首次运行可组合函数进行的绘制过程

Recomposition: 当状态值改变后,再次调用可组合函数进行的绘制过程

可组合函数中的状态

通过remember函数,可组合函数可以在内存中保存一个单例。第一次绘制时,通过remeber记录的值会被保存到这个单例中,再次绘制时,这个值会被返回。remember 可以用来存储可变或不可变的对象

注意: 当这个UI组件被从整个UI树上移除时,remember记录的这个单例会被回收

mutableStateOf 函数创建一个类型为 MutableState的可观察对象

interface MutableState<T> : State<T> {
   
    override var value: T
}

value的改变会通知所有订阅了该可观察对象的可组合函数,并触发它们的重绘。

可组合函数中有三种方式定义一个 MutableState 对象

  • val mutableState = remember { mutableStateOf(default) }
  • var value by remember { mutableStateOf(default) }
  • val (value, setValue) = remember { mutableStateOf(default) }

这三种声明是等价的,选择一种对你来说最容易阅读的即可

注意使用by委托的写法,需要这两个依赖

import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue

通过remember保存的变量,不仅可以作为其他可组合函数的入参,还可以参与逻辑控制。例如下面对name的非空判断

@Composable
fun HelloContent() {
   
   Column(modifier = Modifier.padding(16.dp)) {
   
       var name by remember {
    mutableStateOf("") }
       if (name.isNotEmpty()) {
   
           Text(
               text = "Hello, $name!",
               modifier = Modifier.padding(bottom = 8.dp),
               style = MaterialTheme.typography.h5
           )
       }
       OutlinedTextField(
           value = name,
           onValueChange = {
    name = it },
           label = {
    Text("Name"
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值