Jetpack Compose如何不修改原函数实现Composable重父级并保留内部状态
解决方案
可以在完全不修改FooBar函数的前提下实现状态保留,根据你的Compose版本可以选择以下两种方案:
方案1:使用movableContentOf(推荐,适配普通remember存储的状态)
Jetpack Compose 1.2.0及以上版本提供的movableContentOf API,专门用于将Composable内容在组合树的不同位置移动,全程不会丢失内部的所有状态,完全不需要修改目标Composable的实现。
具体实现步骤:
- 在布局层级之上的稳定作用域(不会随父布局变更销毁的作用域,比如Activity、外层Screen的Composable中),将
FooBar包装为可移动内容:
val movableFooBar = remember { movableContentOf { FooBar() } }
- 无论外层布局结构如何调整,直接调用包装后的
movableFooBar即可:
原有布局:
Box { Box { movableFooBar() } }
调整后的布局:
Box { Row { movableFooBar() } }
该方案下FooBar内部的UUID不会发生变化,所有内部状态都会完整保留。
方案2:使用SaveableStateHolder(适配rememberSaveable存储的状态,支持跨配置变更保留)
如果FooBar内部的状态是通过rememberSaveable存储,且需要支持屏幕旋转等配置变更后依然保留状态,可以使用该方案:
- 在稳定作用域创建状态持有者和唯一标识键:
val stateHolder = rememberSaveableStateHolder() const val FOO_BAR_UNIQUE_KEY = "foobar_key"
- 布局调用时用
SaveableStateProvider包裹FooBar:
Box { // 外层是Box或者Row都不影响 Row { stateHolder.SaveableStateProvider(key = FOO_BAR_UNIQUE_KEY) { FooBar() } } }
内容的提问来源于stack exchange,提问作者AChep
相关产品推荐
相关产品推荐

