Compose中的重组、state、remember

文章目录

  • 一、前言
  • 二、示例代码
  • 三、参考链接:

一、前言

在Compose中UI采用State状态来控制UI变化,根据状态的不同来显示不同的内容,每次UI的重新变化成为重组。通过remember可以将state的数据保存起来(或者实例对象,毕竟条件不改变的话默认只会执行一次remember中的函数,哪怕重组无数次),避免在重组期间进行重置。下面记录下三者的关联。
其中个人感觉state和remember不是必须的,如果能主动触发组件重组获取新数据,那么完全可以不使用state去存储数据。如果把变量存储在一个公共空间,在组件重组期间不会重新生成实例对象,那么也可以不使用remember来进行保存对象(虽然事实上remember最终也是定义了一个kotlin文件级别的变量来进行存储数据)。虽然如此,但是能用state和remember的话还是使用的好,因为实际开发中UI页面很复杂,自己精细去控制某一个组件的重组的话会很麻烦。

二、示例代码

如下是一个简单的Compose代码,用来显示文本

@Composable
fun TestWidget(){
    Column {
        Text(text = "这是一个文本")
    }
}

然后增加一个按钮来改变文本

var count = 0
@Composable
fun TestWidget(){
   
    Column {
        Button(onClick = { count += 1 }) {
            Text(text = "点我")
        }
        Text(text = "这是一个文本:${count}")
    }
}

运行后会发现点击按钮没有效果,这是因为在Compose中没有对数据进行直接观察,是通过State来承载数据然后,监听State的变化来变化UI的。如果想要改变需要修改为以下代码

private val count = mutableIntStateOf(0)
@Composable
fun TestWidget(){
    Column {
        Button(onClick = { count.intValue += 1 }) {
            Text(text = "点我")
        }
        Text(text = "这是一个文本:${count.intValue}")
    }
}

将变量count定义在函数内部然后重新运行会发现数据UI还是没有变化

@Composable
fun TestWidget(){
    val count = mutableIntStateOf(0)
    Log.e("YM--->","--->Test重组")
    Column {
        Button(onClick = { count.intValue += 1 }) {
            Text(text = "点我")
        }
        Text(text = "这是一个文本:${count.intValue}")
    }
}

这里通过日志可以发现每次点击按钮,函数都会重新执行,这样就导致了count每次都会重新初始化变量,所以需要用一个方式将内容进行保存,比如官方提供的remember或者其余方式

@Composable
fun TestWidget(){
    val count = remember {
        Log.e("YM--->","--->remember")
        mutableIntStateOf(0)   
    }
    Log.e("YM--->","--->Test重组")
    Column {
        Button(onClick = { count.intValue += 1 }) {
            Text(text = "点我")
        }
        Text(text = "这是一个文本:${count.intValue}")
    }
}

执行代码会发现remember{}函数中代码仅仅执行了一次,这样就保证了State的变量为同一个实例(将State放在别的地方只要能保证同一个变量也是可以的)。如果想根据情况去刷新这个实例对象可以根据情况设置key值

 val count = remember(key1 = "A") {
        Log.e("YM--->","--->remember")
        mutableIntStateOf(0)
    }

注意: State的变量如果在Compose重组范围内定义,最好用remember去存储,因为这样的话可以避免不知道哪里的重组就导致了数据的重新初始化。

三、参考链接:

  1. 了解 Compose 的重组作用域
  2. Compose 编程思想
  3. 构建 Compose 界面
  4. 状态和 Jetpack Compose
  5. Jetpack Compose 中的高级状态和附带效应

你可能感兴趣的:(JetPack,android)