简体   繁体   English

如何在jetpack compose中显示具有适当大小/布局的垂直文本

[英]How to show vertical text with proper size/layout in jetpack compose

How does one properly rotate text in jetpack compose and get it to do a correct layout?如何正确旋转jetpack compose中的文本并使其进行正确的布局? When I use the rotate modifier on a Text object the text is rotated but the size taken up in the layout seems to be using the pre-rotated text width.当我在文本 object 上使用rotate修饰符时,文本被旋转,但布局中占用的大小似乎使用了预旋转的文本宽度。

Here is a simple example of what I am trying to accomplish - the vertical text should be along the left side in a narrow space:这是我想要完成的一个简单示例 - 垂直文本应该在狭窄空间的左侧:

@Composable
fun MainBox() {
    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(
            modifier = Modifier.padding(4.dp).background(Color.Gray),
            text = "This is at the top"
        )

        Row(
            modifier = Modifier.fillMaxWidth().weight(1f),
            verticalAlignment = Alignment.CenterVertically
        ) {

            Text(
                modifier = Modifier.padding(4.dp).rotate(-90f),
                text = "This should be vertical text on the left side"
            )

            Text(
                modifier = Modifier.fillMaxSize().background(Color.Yellow),
                textAlign = TextAlign.Center,
                text = "This is a big yellow box that should take up most of the space"
            )
        }
    }
}

However, what this shows is this.然而,这表明了这一点。

长的垂直文本

If I shorten the text in the vertical text it only takes up a narrow space, which looks more like the layout I want.如果我缩短竖排文本中的文本,它只占用一个狭窄的空间,看起来更像我想要的布局。

短垂直文本

Is there a way to intercept the layout process or some other setting to use to fix the sizes so that the vertical text takes up only one text row's width of horizontal space, but still adapts to user font size changes (so no fixed sizes)?有没有办法拦截布局过程或其他一些设置来固定大小,以便垂直文本只占用一个文本行的水平空间宽度,但仍然适应用户字体大小的变化(所以没有固定大小)?

Answers to similar questions here and here do not solve this problem or no longer work. 此处此处的类似问题的答案不能解决此问题或不再有效。

My version.我的版本。 After a few tests it seems to work pretty well经过几次测试,它似乎工作得很好

class ComposeActivity7 : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            ComposeTutorialTheme {

                Column(
                    modifier = Modifier.fillMaxSize(),
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    Text(
                        modifier = Modifier
                            .padding(4.dp)
                            .background(Color.Gray),
                        text = "This is at the top"
                    )

                    Row(
                        modifier = Modifier
                            .fillMaxWidth()
                            .weight(1f),
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Text(
                            modifier = Modifier
                                .vertical()
                                .rotate(-90f)
                                .background(Color.Gray)
                                .padding(4.dp),
                            text = "This should be vertical text on the left side"
                        )
                        Text(
                            modifier = Modifier
                                .fillMaxSize()
                                .background(Color.Yellow),
                            textAlign = TextAlign.Center,
                            text = "This is a big yellow box that should take up most of the space"
                        )
                    }
                }
            }
        }
    }
}

fun Modifier.vertical() =
    layout { measurable, constraints ->
        val placeable = measurable.measure(constraints)
        layout(placeable.height, placeable.width) {
            placeable.place(
                x = -(placeable.width / 2 - placeable.height / 2),
                y = -(placeable.height / 2 - placeable.width / 2)
            )
        }
    }

Result结果

在此处输入图像描述

Slightly improved variant of Sergei S, which works within parents which have Modifier.high(Intrinsic.X) :稍微改进的 Sergei S 变体,它适用于具有Modifier.high(Intrinsic.X)的父母:

fun Modifier.rotateVertically(rotation: VerticalRotation) = then(
    object : LayoutModifier {
        override fun MeasureScope.measure(measurable: Measurable, constraints: Constraints): MeasureResult {
            val placeable = measurable.measure(constraints)
            return layout(placeable.height, placeable.width) {
                placeable.place(
                    x = -(placeable.width / 2 - placeable.height / 2),
                    y = -(placeable.height / 2 - placeable.width / 2)
                )
            }
        }

        override fun IntrinsicMeasureScope.minIntrinsicHeight(measurable: IntrinsicMeasurable, width: Int): Int {
            return measurable.maxIntrinsicWidth(width)
        }

        override fun IntrinsicMeasureScope.maxIntrinsicHeight(measurable: IntrinsicMeasurable, width: Int): Int {
            return measurable.maxIntrinsicWidth(width)
        }

        override fun IntrinsicMeasureScope.minIntrinsicWidth(measurable: IntrinsicMeasurable, height: Int): Int {
            return measurable.minIntrinsicHeight(height)
        }

        override fun IntrinsicMeasureScope.maxIntrinsicWidth(measurable: IntrinsicMeasurable, height: Int): Int {
            return measurable.maxIntrinsicHeight(height)
        }
    })
    .then(rotate(rotation.value))

enum class VerticalRotation(val value: Float) {
    CLOCKWISE(90f), COUNTER_CLOCKWISE(270f)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM