旋转时在屏幕的所有边缘对齐可组合项

Posted

技术标签:

【中文标题】旋转时在屏幕的所有边缘对齐可组合项【英文标题】:Align Composables on all the edges of the screen while rotated 【发布时间】:2022-01-24 01:46:09 【问题描述】:

我似乎无法弄清楚如何在 Jetpack Compose 中对齐。 这是我希望它看起来的样子:

现在我尝试了以下方法,但它没有按预期工作: 顺便说一句,不要介意确切的颜色,我只对如何定位这些视图的概念感兴趣,每个视图旋转 90 度,并在我的情况下与平板电脑的边缘对齐


// Large green background
    Box(modifier = Modifier.fillMaxSize().background(Color.DarkGray))
    

        Box(
            Modifier
                .fillMaxSize()
                .background(Color.Green),
            contentAlignment = Alignment.BottomCenter
        )  Text("Player 1") 

        Box(
            Modifier
                .fillMaxSize()
                .background(Color.Green)
                .rotate(90f),
            contentAlignment = Alignment.CenterStart
        )  Text("Player 2") 

        Box(
            Modifier
                .fillMaxSize()
                .background(Color.Green)
                .rotate(180f),
            contentAlignment = Alignment.TopCenter,
        )  Text("Player 3") 

        Box(
            Modifier
                .fillMaxSize()
                .background(Color.Green)
                .rotate(-90f),
            contentAlignment = Alignment.CenterEnd
        )  Text("Player 4") 

    

我要么缺少对齐选项,要么缺少为旋转设置枢轴点的方法。 有人有什么建议吗?

我目前正在使用:

AS 2020.3.1 - 补丁 4 编写 1.1.0-rc01 Kotlin 1.6.0 Agp:7.0.4

【问题讨论】:

【参考方案1】:

    Modifier.fillMaxSize() 使您的所有项目都与父项一样大,并且由于它们被放置在 Box 容器中 - 只有顶部的项目可见。这种布局不需要此修饰符。

    通过应用contentAlignment = Alignment.CenterStart,您将布局Box 子视图,例如你的文字。相反,您需要将项目相对于父容器对齐,这可以使用 Modifier.align(Alignment.CenterStart)

    Modifier.rotate 不会改变视图位置,所以需要在旋转后手动更新。要了解发生了什么,您可以运行以下代码:

    Box(
        contentAlignment = Alignment.Center,
        modifier = Modifier.fillMaxSize()
    ) 
        Box(Modifier
            .size(100.dp, 50.dp)
            .border(width = 1.dp, color = Color.Red)
            .rotate(90f)
            .background(Color.Green))
    
    

    它将产生以下视图:

    如您所见,实际视图框架显示为红色边框,并且您的视图具有意外偏移。您可以使用Modifier.layout 修复它,如下所示:

    fun Modifier.layout90Rotated() =
        layout  measurable, constraints ->
            val placeable = measurable.measure(constraints)
            layout(placeable.height, placeable.width) 
                placeable.place(-placeable.height, (placeable.width - placeable.height) / 2)
            
        
    

    最后一步是将Modifier.background 移动到修饰符列表的末尾。在this answer中查看为什么修饰符顺序很重要

最终代码如下所示:

Box(modifier = Modifier.fillMaxSize().background(Color.DarkGray))

    Box(
        modifier = Modifier
            .align(Alignment.BottomCenter)
            .background(Color.Green)
    )  Text("Player 1") 

    Box(
        modifier = Modifier
            .align(Alignment.CenterStart)
            .rotate(90f)
            .layout90Rotated()
            .background(Color.Green)
    )  Text("Player 2") 

    Box(
        modifier = Modifier
            .align(Alignment.TopCenter)
            .rotate(180f)
            .background(Color.Green)
    )  Text("Player 3") 

    Box(
        modifier = Modifier
            .align(Alignment.CenterEnd)
            .rotate(-90f)
            .layout90Rotated()
            .background(Color.Green)
    )  Text("Player 4") 


结果:

【讨论】:

以上是关于旋转时在屏幕的所有边缘对齐可组合项的主要内容,如果未能解决你的问题,请参考以下文章

如何在 UIButton 的右边缘对齐 UIButton 图像

使用 Bootstrap 对齐左边缘时居中列表项

javafx 组合框下拉菜单从屏幕边缘出来

android编程用怎么让控件的“右边”对齐在屏幕的中心?

图像视图autolayout从水平边缘固定到60pt,但自动刻度高度?

在swift 3中获取与边缘的距离