我有两项活动:ActivityOne.kt
和ActivityTwo.kt
。它们都使用Jetpack Compose来显示UI。在第一个示例中,必须显示一个项目(比如Text
),变量showtText
为true
,如果为false,则隐藏该项目。我使用以下代码来实现:
@Composable
fun MyUI(){
AnimatedVisibility(visible = viewModel.showText) {
Text("Some text")
}
}
我的变量showText
是在ViewModel中定义的,例如:
val showText by mutableStateOf(false)
这样,当ActivityOne.kt
可见时,我在ViewModel中更改showText
的值时,它会出现或消失。
1.用户可以从ActivityOne.kt
导航到ActivityTwo.kt
(第一个在后台运行,不会从堆栈中清除)。
1.这里有一个Switch
可以切换showText
的值。
1.当用户按下“返回”时,ActivityTwo.kt
调用finish()
,它消失了,再次显示ActivityOne.kt
(它在堆栈中)。
1.如果用户已在ActivityTwo.kt
中切换showText
值,则文本应自动隐藏或显示,因为showText
的状态已更改。
问题是,尽管showText
的值确实发生了变化,但ActivityOne.kt
中的UI并没有对这些变化做出响应。我检查了ActivityOne.kt
的UI在ActivityTwo.kt
完成后没有发生重组,因为它没有记住showText
的先前状态。
我怎么能做到呢?提前感谢!
EDIT 1这个问题比我解释的要难一些,但是基础是一样的。下面是我的完整代码:
- 练习一.kt:*
class ActivityOne : ComponentActivity() {
private lateinit var vm: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val vmFactory = MainViewModelFactory()
vm = ViewModelProvider(this, vmFactory).get(MainViewModel::class.java)
setContent {
MyTheme {
Surface {
MyUI()
}
}
}
}
@Composable
fun MyUI() {
AnimatedVisibility(visible = myPrefs.showText) {
Text("Some text")
}
}
}
- 主视图模型.kt:*
class MainViewModel : ViewModel() {
companion object {
val myPrefs by mutableStateOf( AppPrefs() )
}
}
- 练习二.kt:*
class ActivityTwo : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyTheme {
Surface {
MyUI2()
}
}
}
}
@Composable
fun MyUI2() {
val showText = remember {
mutableStateOf(MainViewModel.myPrefs.showText)
}
Switch(
checked = showText.value,
onCheckedChange = {
showText.value = it
MainViewModel.myPrefs.showText = it
}
)
}
}
- 应用程序首选项kt:*
class AppPrefs {
var showText: Boolean = false
}
1条答案
按热度按时间toe950271#
因为
mutableStateOf
正在跟踪myPrefs
的状态,而myPrefs
的状态从未改变(引用本身从未改变),所以未发生重组。您可以通过几种方式实现重组。
在这里,我假设您的
AppPrefs
类已经包含了多个成员/字段,或者您希望在将来轻松地向其添加更多成员。这就是为什么我在下面的示例中向其添加了2个属性,并且我只建议添加更多成员不会影响现有代码的解决方案。选项1
如果可以更改
AppPrefs
类以分别跟踪每个属性的状态,则进行以下更改其他的一切都保持不变。这里重新组合再次工作,因为现在状态是在实际被更改的成员上跟踪的。
选项2
如果你不能(或者不想)在
AppPrefs
中包含mutableStateOf
,你可以将AppPrefs
从普通的class
修改为data class,这样你就可以自动实现copy
函数(与equals
、hashCode
、toString
和componentN
一起实现反结构化)。在这种情况下,还必须更改
myPrefs
值的更改方式。如果您不能使用数据类,那么您仍然可以使用选项2,但是您要在现有的类上实现
copy
函数作为奖励,如果您使用上述任何一种解决方案,您甚至可以简化
MyUI2
可组合代码的现有代码,并且重新组合仍然有效。示例: