前言
Google将自己开发的Gemini(声称可与ChatGPT4一较高下,看了下宣传视频,确实不耐)引入到了Bard,所以关于这个问题,首先问了下Bard:
我: LaunchedEffect 参数key的作用?
它:
回答怎么样?感觉很专业对不对,其实里面 暗含错误。有一本正经的胡说八道之嫌。
实际写过LaunchedEffect,并检验过入参key在是否改动过对重组时的影响便可知:
- key如果是常量:true, “不变的字符串”, 或直接写null,那么LaunchedEffect只会在该组合函数第一次组合时执行一次,之后便不再执行。
- 如果key是一个变量,比如将已定义好的myKey(定义var myKey = ”abc”)赋值给LauchedEffect中的key,当我们在onClick中改变这个值时,LauchedEffect不会立即执行,而是会在下次重组时才会再次执行LaunchedEffect,这也是看了官方文档后仍然容易误解的地方。
- 当传入的key是一个状态值(var myState = remember{ mutableStateOf(0)} ),不受上面所说的影响,myState只要有变化,则LaunchedEffect会立即执行。
- 还有一点,在之前的文章里也提到过:在发生重组时,副作用函数不一会被执行到,要确保副作用函数在重组范围内。(智能重组)
开始说说produceState
在实际应用中有两方面的作用:
- 产生联动效果:
假如有这样的需求:页面一分为二,左边一个有多种颜色的色板,右边会根据左边选出的颜色而变化。
代码可以写成这样:
val selectedColor = remember { mutableStateOf(Color.White) }
val backgroundColor = produceState(initialValue = Color.White) {
selectedColor.value.let { color ->
val colorInt = color.toArgb()
val red = Color.red(colorInt)
val green = Color.green(colorInt)
val blue = Color.blue(colorInt)
value = Color.rgb(red, green, blue)
}
}
当手指在左侧选择不同的颜色时,也就是selectedColor会发生发变,相应的backgroundColor也会变化,产生了联动效果。
- 将非Compose状态转为Compose状态,举个例子,将flow转为state
val numberFlow = flow {
repeat(100) {
delay(1000)
emit(it)
}
}
var myState = produceState(initialValue = 1f, key1 = numberFlow, producer = {
numberFlow.collect(){
value = it.toFloat()
}
})
OutlinedButton(onClick = {
}) {
Text(text = "btn: $myState.value")
}
运行后,OutlineButton上的数字增长100次。同样的LiveData也同样可转为state