【问题标题】:Android getting layout width & height for ComposeAndroid 获取 Compose 的布局宽度和高度
【发布时间】:2021-08-31 21:50:41
【问题描述】:

如何使用 compose 获取实际大小值?如果在将数据提供给视图之前必须完成布局大小的操作?我不喜欢检查。当每次画布重绘时

    Box {
        var count by rememberSaveable {
            mutableStateOf(0)
        }
        var states = remember { mutableListOf<Rain>() }
        Canvas(modifier = Modifier.fillMaxSize()) {
            // i need the canvas' size so i initialize the object inside this scope, and check it every time when canvas redraws
            Log.e("canvas", "repainted")
            if(states.isEmpty()) states.addAll(MutableList(300) {
                Rain(size.width, size.height)
            })
            drawRect(color = Color.Black)
            repeat(300) {
                val c = count
                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++
            }
        }
    }

【问题讨论】:

    标签: android kotlin android-jetpack-compose


    【解决方案1】:

    您可以将canvasSize 保存到状态变量中,然后将derivedStateOf 用于您的states:只有在更改内部使用的任何可变状态时才会重新计算此块的内容,在这种情况下它将是canvasSize

    Box {
        var count by rememberSaveable {
            mutableStateOf(0)
        }
        var canvasSize by remember { mutableStateOf(Size.Unspecified) }
        val states by remember(canvasSize) {
            derivedStateOf {
                List(300) {
                    Rain(canvasSize.width, canvasSize.height)
                }
            }
        }
        Canvas(
            modifier = Modifier
                .fillMaxSize()
        ) {
            canvasSize = size
            drawRect(color = Color.Blue)
            repeat(300) {
                val x1 = states[it].x1
                val x2 = states[it].x2
                val y1 = states[it].y1
                val y2 = states[it].y2
                drawLine(start = Offset(x1, y1), end = Offset(x2, y2), color = color)
            }
            states[it]()
        }
        LaunchedEffect(isPaused) {
            while (!isPaused) {
                delay(40)
                count++
            }
        }
    }
    

    【讨论】:

    • 对不起,我不知道如何使用记住在 drawScope 中创建状态,撰写调用只能在可组合函数的上下文中发生,它是这么说的。我必须实现我自己的?
    • 你的意思是 Canvas 内部的可变状态本身就是一种记忆吗?
    • @user16799920 我误解了你的问题,检查更新
    • 谢谢,它确实有效。我的语言不好理解是错误的。
    【解决方案2】:

    DrawScope 里面有一些属性,其中之一是size,它本身有 widthheightminDimensionma​​xDimension 属性。

    Canvas {
           size.width
           size.height
    }
    

    其他人

    @DrawScopeMarker
    interface DrawScope : Density {
    
        /**
         * The current [DrawContext] that contains the dependencies
         * needed to create the drawing environment
         */
        val drawContext: DrawContext
    
        /**
         * Center of the current bounds of the drawing environment
         */
        val center: Offset
            get() = drawContext.size.center
    
        /**
         * Provides the dimensions of the current drawing environment
         */
        val size: Size
            get() = drawContext.size
    
        /**
         * The layout direction of the layout being drawn in.
         */
        val layoutDirection: LayoutDirection
    ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-01
      • 2012-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-03
      • 2014-02-16
      • 1970-01-01
      相关资源
      最近更新 更多