前言

在前面聊mutableStateOf 的时分用了这段代码来讲述了Compose 状况的更新。

code-1
valname=mutableStateOf("hellocompose")
setContent{
Text(name.value)
}
lifecycleScope.launch{
delay(3000)
name.value="android"
}

接下来,咱们继续通过这段代码来一同聊下 Composeremember

浅聊

咱们先对code-1的代码略微做下修正

code-2
setContent{
varnamebymutableStateOf("hellocompose")
Text(name)
//ps:此处代码仅做演示运用,compose中协程的运用并非如此
lifecycleScope.launch{
delay(3000)
name="android"
}
}

当咱们这样进行修正之后,发现3s往后,“hello compose” 并没有如期变成“android”。

这是为什么呢? 是协程没有执行吗?还是没有进行重组改写?用最简略的方法,咱们来加日志看一下执行。

code-3
setContent{
Log.i("TAG","setContent:")
varnamebymutableStateOf("hellocompose")
Text(name)
//ps:此处代码仅做演示运用,compose中协程的运用会另做解说。
lifecycleScope.launch{
delay(3000)
name="android"
Log.i("TAG","launch:")
}
}

简单聊聊 compose 的remember

可以看到,协程现已执行了,而且也进行了重组改写,可是为什么值没有改动呢?

这是由于运用变量的组件会被包起来,当变量改动的时分会随之进行重组改写,每次改写的时分,就会从头创立一个MutableState目标,这个目标就会取默认值“hello compose”。所以才会看起来每次都进行了改写,可是文字却没有任何改动。

改写重组的范围就叫做重组作用域

咱们想让Text() 进行改写怎么办?可以进行包一层。咱们对code-2的代码略微做下修正。

code-4
setContent{
varnamebymutableStateOf("hellocompose")
Button(onClick={}){
Text(name)
}
//ps:此处代码仅做演示运用,compose中协程的运用会另做解说。
lifecycleScope.launch{
delay(3000)
name="android"
}
}

咱们让Button 对他进行一个包裹,然后来看看作用。

简单聊聊 compose 的remember

可以看到进行包裹了之后,文字发生了改动。尽管这样满意了咱们的需求,可是不能每次有运用变量的组件,每次都进行一个包裹吧,这岂不是会疯掉。

接下来就需求有请咱们今日的主角 remember了,它便是为了协助咱们处理这个问题。

它可以在每次重组的时分,去帮咱们去拿现已缓存的值,不需求每次都是从头创立。

code-5
setContent{
varnamebyremember{mutableStateOf("hellocompose")}
Text(name)
//ps:此处代码仅做演示运用,compose中协程的运用会另做解说。
lifecycleScope.launch{
delay(3000)
name="android"
}
}
简单聊聊 compose 的remember

remember 也是一个Composable 函数,因而只能在Composable 中调用。

现在,咱们有个场景,咱们需求频频调用某个Compposable, 而且参数很多相同且频频切换,假如直接用参数进行展现的话,会形成一些不必要的核算。

为了避免不必要的资源浪费,咱们也可以运用remember 来处理。

code-6
        setContent {
            var name by remember { mutableStateOf("hello compose") }
            Column {
                Button(onClick = {
                    val rnds = (0..2).random()
                    name = "随机数:$rnds"
                }) {
                    Text("按钮")
                }
                ShowCharLenth(name)
            }
        }
@Composable
fun ShowCharLenth(value: String) {
    val length = remember { value.getLength() }
    Text("字符串的长度:$length")
}
fun String.getLength(): Int {
    //模仿复杂的核算
    return this.length
}

这样运用,就避免了code-7 中的频频核算重组。

可是这样还会发生一个问题,假如咱们展现的数据发生了改变, 前面的数据进行了缓存,后边的数据即便变了 还会取之前缓存的数据,那直接发生的问题便是数据改动了,可是UI上没有改变。

remember 也早就对这种状况有了处理办法,而且十分简略。

code-8
@Composable
fun ShowCharLenth(value: String) {
    val length = remember(value) { value.getLength() }
    Text("字符串的长度:$length")
}

括号中的value 便是一个key值,根据key值 再去拿remember缓存的数据,这样就完美处理了咱们的问题。

至此,咱们从这段很短的代码中学到了 remember 的作用 以及运用,感兴趣的同学可以简略上手实践下。

总结

今日的内容就到这儿了,十分的简略,首要便是介绍了一下 remember的作用和运用,期望关于新上手Compose的同学有所协助。