Jetpack Compose获取布局宽高 避免Canvas每次重绘时重复校验
Jetpack Compose 获取布局尺寸及Canvas重绘优化方案
核心实现思路
获取Compose元素的实际布局尺寸可使用官方提供的Modifier.onSizeChanged修饰符,该回调仅在元素测量布局完成、尺寸发生变化时触发,不会随视图重绘反复执行,完美适配你的需求:仅在尺寸确定时执行一次和布局尺寸相关的初始化操作,不需要在每次Canvas重绘时做校验。
优化后代码
Box { var count by rememberSaveable { mutableStateOf(0) } // 存储Canvas实际布局尺寸 var canvasSize by remember { mutableStateOf(IntSize.Zero) } // 以canvasSize为remember的key,尺寸变化时自动重新生成Rain列表 val states = remember(canvasSize) { mutableListOf<Rain>().apply { if (canvasSize != IntSize.Zero) { addAll(MutableList(300) { Rain(canvasSize.width, canvasSize.height) }) } } } Canvas( modifier = Modifier .fillMaxSize() // 仅尺寸变化时触发该回调 .onSizeChanged { canvasSize = it } ) { Log.e("canvas", "repainted") drawRect(color = Color.Black) // 尺寸未初始化完成时跳过绘制逻辑 if (canvasSize == IntSize.Zero || states.isEmpty()) return@Canvas repeat(300) { val x1 = states[it].x1 val x2 = states[it].x2 val y1 = states[it].y1 val y2 = states[it].y2 val color = states[it].color drawLine(start = Offset(x1, y1), end = Offset(x2, y2), color = color) states[it]() } } LaunchedEffect(isPaused) { while (!isPaused) { delay(40) count++ } } }
优化说明
- 完全移除了Canvas绘制作用域内的初始化校验逻辑,绘制流程仅保留纯绘制操作,大幅降低重绘开销
- Rain列表仅在Canvas尺寸首次确定、后续尺寸发生变更(如屏幕旋转、窗口大小调整)时才会重新生成,不会随count更新触发的重绘反复执行初始化
- 逻辑分层清晰,布局测量、数据初始化、视图绘制三个流程完全解耦
内容的提问来源于stack exchange,提问作者user16799920
相关产品推荐
相关产品推荐

