You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 22:39:02