前言
在前面聊mutableStateOf
的时分用了这段代码来讲述了Compose
状况的更新。
code-1
valname=mutableStateOf("hellocompose")
setContent{
Text(name.value)
}
lifecycleScope.launch{
delay(3000)
name.value="android"
}
接下来,咱们继续通过这段代码来一同聊下 Compose
的remember
。
浅聊
咱们先对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:")
}
}
可以看到,协程现已执行了,而且也进行了重组改写,可是为什么值没有改动呢?
这是由于运用变量的组件会被包起来,当变量改动的时分会随之进行重组改写,每次改写的时分,就会从头创立一个MutableState
目标,这个目标就会取默认值“hello compose”。所以才会看起来每次都进行了改写,可是文字却没有任何改动。
改写重组的范围就叫做重组作用域。
咱们想让Text()
进行改写怎么办?可以进行包一层。咱们对code-2
的代码略微做下修正。
code-4
setContent{
varnamebymutableStateOf("hellocompose")
Button(onClick={}){
Text(name)
}
//ps:此处代码仅做演示运用,compose中协程的运用会另做解说。
lifecycleScope.launch{
delay(3000)
name="android"
}
}
咱们让Button
对他进行一个包裹,然后来看看作用。
可以看到进行包裹了之后,文字发生了改动。尽管这样满意了咱们的需求,可是不能每次有运用变量的组件,每次都进行一个包裹吧,这岂不是会疯掉。
接下来就需求有请咱们今日的主角 remember
了,它便是为了协助咱们处理这个问题。
它可以在每次重组的时分,去帮咱们去拿现已缓存的值,不需求每次都是从头创立。
code-5
setContent{
varnamebyremember{mutableStateOf("hellocompose")}
Text(name)
//ps:此处代码仅做演示运用,compose中协程的运用会另做解说。
lifecycleScope.launch{
delay(3000)
name="android"
}
}
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
的同学有所协助。