如何避免AndroidView的update块中所有代码被执行?
Android Compose AndroidView 优化问题解决方案
问题描述
我们有如下Composable代码:
@Composable fun CustomMapView( isActive: Boolean, currentlyDisplayedText: String, ) { AndroidView( factory = { MapView(it) }, update = { mapView -> mapView.addLayer( isActive = isActive, title = currentlyDisplayedText, ) mapView.reorderLayers() }, ) }
当前问题:每当isActive或currentlyDisplayedText状态变化时,update块会整体执行。但实际仅当currentlyDisplayedText变化时才需要调用mapView.reorderLayers(),isActive单独变化时触发该方法属于冗余操作,需要优化。
此前尝试:查阅Compose文档了解到update块会在其读取的状态变化时整体重执行;曾误以为LaunchedEffect或remember无法在该场景使用,导致未找到有效方案。
解决方案
方案一:用remember跟踪状态变化
在CustomMapView的Composable作用域内使用remember保存currentlyDisplayedText的历史值,在update块中对比当前值与历史值,仅当文本实际变化时才调用重排序方法。
修改后的代码:
@Composable fun CustomMapView( isActive: Boolean, currentlyDisplayedText: String, ) { // 保存上一次的文本值,初始化为当前传入的文本 val lastDisplayedText = remember { mutableStateOf(currentlyDisplayedText) } AndroidView( factory = { MapView(it) }, update = { mapView -> // 更新图层的基础状态(无论哪个参数变化都需要执行) mapView.addLayer( isActive = isActive, title = currentlyDisplayedText, ) // 仅当文本发生变化时执行重排序 if (currentlyDisplayedText != lastDisplayedText.value) { mapView.reorderLayers() // 更新历史值,确保下次对比准确 lastDisplayedText.value = currentlyDisplayedText } }, ) }
补充说明
remember是Composable作用域的API,CustomMapView本身就是Composable,因此完全可以在其中使用,之前的误解不成立。- 如果
addLayer支持部分参数更新(比如单独更新isActive或title),可以进一步拆分逻辑,但如果必须传入完整参数,上述方案已经能解决冗余调用的问题。
内容的提问来源于stack exchange,提问作者Mark Frelih
相关产品推荐
相关产品推荐

