我正在做实验来理解重组和智能重组并制作了一个样本
\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
想象一下下面的物体
data class CourseState(
val key:Int=0,
val name:String="",
val courses:Courses=Courses())
Run Code Online (Sandbox Code Playgroud)
实现以下模式
private val _courseState = mutableStateOf(CourseState())
val courseState: State<CourseState> = _courseState
Run Code Online (Sandbox Code Playgroud)
我可以通过调用以下命令来触发 UI 的重构:
_courseState.value = CourseState()
Run Code Online (Sandbox Code Playgroud)
但不是通过调用:
_courseState.value.courses.addCourse(Course("some course))
Run Code Online (Sandbox Code Playgroud)
这有点令人沮丧,因为即使该对象明显发生了变化,我也被迫创建父对象的一个全新实例,以便引发其中的微小变化。
现在,我知道 Compose 在幕后使用该.equals()方法来确定是否应该重新组合布局,因此我对如何实现所需的行为有了一些想法。
覆盖该equals方法:这将意味着一些样板代码,并且必须对构成我的对象的整个嵌套类集完成。这可能有效,但看起来危险且麻烦。
使用clone接受其自己类的实例作为参数的方法或构造函数来创建对象的相同副本,该副本仍然代表我可以修改的新实例,然后作为可变状态值传递。听起来比之前的选择更容易,但优雅是不同的
深入研究 State 和 MutableState 类,看看是否有办法让它们按照我想要的方式运行。我依赖你们中的一些人以前做过这件事,所以我不必 XD
让我知道你的想法,或者是否有其他一些明显的解决方案到目前为止我还没有想到
android kotlin android-jetpack-compose compose-recomposition
为了在 jetpack compose 中存储状态,到目前为止我使用了以下模式:
private val _largeDataClass:MutableState<LargeDataClass> = mutableStateOf(LargeDataClass())
val largeDataClass :State<LargeDataClass> = _largeDataClass
Run Code Online (Sandbox Code Playgroud)
然后我在我的作品中显示该类的部分或全部属性。当用户更改此数据类的属性时,我需要更新状态,并按以下方式执行操作:
fun onUserEvent(somePropertyChange:String){
_largeDataClass.value=largeDataClass.value.copy(someProperty = somePropertyChange)
}
Run Code Online (Sandbox Code Playgroud)
我从以下帖子中得到了这种方法。它有效并且具有保持我的代码库相对较小的好处(因为可能有 20 多个不同的属性,LargeDataClass我不需要单独声明为可变状态)但是,如果我没有记错的话,遵循这种方法将触发我的代码的重组整个屏幕,即使用户只是在我的众多 .txt 文件中键入一个字母TextFields。由于我的所有可组合项都显示 largeDataClass 的某些属性,并且它们刚刚被通知其值已更改。
我的第一个问题是我的最后一个假设是否正确。我当前的保持状态的方式是否会对我的应用程序性能产生负面影响,因为我强制屏幕不断地完全重绘?或者是否有一些我不知道的优化可以防止这种情况发生并使我的应用程序安全?
我的第二个问题:如果有一种方法可以转换数据类,我真的很喜欢它,比如:
data class Student(
val key: String = "s0",
val firstName: String = "",
val lastName: String = "")
Run Code Online (Sandbox Code Playgroud)
进入等效的状态持有者类(类似于以下内容)
class StudentState(s:Student){
val key= mutableStateOf(s:Key),
val firstName= mutableStateOf(s.firstName),
val lastName= mutableStateOf(s.lastName)}
Run Code Online (Sandbox Code Playgroud)
(理想情况下,不必每次都自己显式编写这样的类)这已经存在吗?有没有办法使用反射或类似的方法来实现通用数据类?
我仍在学习如何处理 jetpack compose 中的状态,我想把它做好。在我看来,在 ViewModel 或 State Holder 类中单独跟踪数据类的属性是正确的做法,但另一方面,这使我的代码更长,而且感觉就像我在做很多东西重复两次,我的代码变得不太可读和可维护。非常感谢任何见解