我正在做实验来理解重组和智能重组并制作了一个样本
\n\n抱歉,颜色是用 Random.nextIn() 生成的,以便在视觉上观察重组,设置颜色对重组没有影响,也尝试不更改颜色。
\ngif的内容由三部分组成
\n样品1
\n@Composable\nprivate fun Sample1() {\n\n Column(\n modifier = Modifier\n .background(getRandomColor())\n .fillMaxWidth()\n .padding(4.dp)\n ) {\n var counter by remember { mutableStateOf(0) }\n\n\n Text("Sample1", color = getRandomColor())\n\n Button(\n modifier = Modifier\n .fillMaxWidth()\n .padding(vertical = 4.dp),\n colors = ButtonDefaults.buttonColors(backgroundColor = getRandomColor()),\n onClick = {\n counter++\n }) {\n Text("Counter: $counter", color = getRandomColor())\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n我在这里没有问题,因为智能组合按预期工作,Text最重要的是不读取更改,counter因此重组仅发生在Textinside Button。
样品2
\n@Composable\nprivate fun Sample2() {\n Column(\n modifier …Run Code Online (Sandbox Code Playgroud) android kotlin android-jetpack-compose compose-recomposition
我一直在使用 Jetpack Compose Desktop。我注意到一些我真的不明白的事情:
import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
@Composable
@Preview
fun App() {
var text by mutableStateOf("Hello, World!")
MaterialTheme {
TextField(text, onValueChange = { text = it })
Button(onClick = {
text = "Hello, Desktop!"
}) {
Text(text)
}
}
}
fun main() = application {
Window(onCloseRequest = ::exitApplication) {
App()
}
}
Run Code Online (Sandbox Code Playgroud)
为什么我可以更改 中的文本TextField?我认为在每次重组时,可变状态都会使用初始值重新实例化:所以Text应该无法更改
import androidx.compose.desktop.ui.tooling.preview.Preview
import …Run Code Online (Sandbox Code Playgroud) 假设我们有接下来的 5 行代码:
@Composable
fun MyParentComposable() {
var myVariable by remember { mutableStateOf(0) }
MyChildComposable(myVariable)
}
Run Code Online (Sandbox Code Playgroud)
我知道每当我们改变时,myVariable我们都会重新组合MyParentComposable,并且MyChildComposable任何其他孩子都会MyChildComposable()阅读该值。
我知道,如果我不在myVariable任何可组合项中使用它MyChildComposable,那么在更改它时它仍然会被重新组合,因为我们正在某处读取它(我猜想在参数中,即使它没有被使用)
我知道,如果我们传递 lambda 并推迟读取,那么只有调用该值的组件和父作用域才会被重构MyChildComposable。
问题是,当传递myVariable到时MyChildComposable,我是在读它还是还有别的东西?
我想查看一些反编译的代码或类似的东西来更深入地理解它,但我不知道应该去哪里。希望有人能在这里提供一些线索,让我可以说“是的,就是因为这个”
这个例子也是如此
@Composable
fun MyParentComposable() {
val myVariable = remember { mutableStateOf(0) }
MyChildComposable(myVariable.value)
}
Run Code Online (Sandbox Code Playgroud)
我正在读取范围中的值MyParentComposable()并将其传递下来MyChildComposable()
编辑:
没有 Lambda 的示例:ParentComposable 和 child 被重新组合,内部没有任何可组合项读取它,只有带有参数的可组合项
@Composable
fun MyParentComposable() {
var myVariable by remember { mutableStateOf(0) …Run Code Online (Sandbox Code Playgroud) 我正在为我的应用程序创建一个自定义滑块控件,但如果不添加一些丑陋的黑客,我无法避免不必要的重组......
CustomSlider1是一个当值改变时重组其所有子组件的组件;CustomSlider2是我想出的,但代码似乎不正确,所以有人可以告诉我我做错了什么CustomSlider1以及是否CustomSlider2确实正确?
这两个组件之间的区别基本上是我通过 lambda 读取值,并将组件添加到ScopedSlider可组合项中。
我正在使用recomposeHighlighter来显示重组。
这是代码:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
TestTheme {
Column {
var value by remember {
mutableStateOf(50f)
}
CustomSlider1("Custom Slider", value, 50f, true, { value = it }, 0f..100f, 5)
Spacer(modifier = Modifier.padding(10.dp))
CustomSlider2("Custom Slider 2", { value }, 50f, true, { value = it }, 0f..100f, 5)
}
}
}
}
} …Run Code Online (Sandbox Code Playgroud) 我知道Column(){...}当b1orb2改变时,将会重新组合。
如果我希望只有改变的Column(){...}时候才可以重新组合,而改变的 时候不重新组合,怎么办?b2Column(){...}b1
@Composable
fun ScreenDetail(
mViewMode: SoundViewModel
) {
val b1=mViewMode.a1.collectAsState(initial = 0)
val b2=mViewMode.a2.collectAsState(initial = 0)
Column() {
Text(" ${b1.value} ${b2.value}")
Text(Calendar.getInstance().time.toSeconds())
}
}
fun Date.toSeconds():String{
return SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.US).format(this)
}
class SoundViewModel(): ViewModel() {
var i = 0
val a1: Flow<Int> = flow {
while (true) {
emit(i++)
delay(1000)
}
}
val a2: Flow<Int> = flow {
while (true) {
emit(i)
delay(2000)
}
}
}
Run Code Online (Sandbox Code Playgroud)