Jetpack Compose,居中文本而不填充字体?

sub*_*ris 8 android android-jetpack-compose

我正在为 Jetpack Compose alpha-11 版中的垂直居中文本而苦苦挣扎。看来我的字体有大量的填充,我无法找到禁用它的方法。这在 SO 上只出现过一次,据我所知,here,但他们使用约束布局的答案似乎表明他们只是绝对定位它,这与其说是解决方法,不如说是解决方法,以及我想避免的事情。

您可以在下面的屏幕截图中清楚地看到它。

在此处输入图片说明

代码如下所示:

                   Column(verticalArrangement = Arrangement.Center) {
                        Text(
                            text = "Let's Go",
                            color = Color.White,
                            fontSize = 120.sp,
                            fontFamily = oswaldLightFontFamily(),
                            textAlign = TextAlign.Center,
                            modifier = Modifier.background(Color.Blue)
                        )
                    }
Run Code Online (Sandbox Code Playgroud)

您希望定位它的参数 -verticalArrangement并且textAlign- 在这里没有做任何事情,但我将它们包括在内以证明我已经尝试过。

到目前为止,我的解决方法是Modifier.graphicsLayer(translationY = -25f)将其向上移动,但这对于应该如此简单的事情来说似乎是一个可怕的黑客攻击。似乎在经典的 Android 布局中,可以设置android:includeFontPadding="false"并绕过这种行为,但在 Jetpack Compose 中似乎没有类似的选项。

有人遇到这个吗?

Ale*_*dra 13

发生这种情况是由于https://fonts.google.com/specimen/Oswald上的字体填充不均匀,加上您使用的小写文本使差异更加明显。

正如@Siyamed 下面提到的,在 Compose 中关闭默认 includeFontPadding 行为的 API 是随 Compose 1.2 beta 一起发布的,您可以像这样使用它:

Text(
...
   style = TextStyle(
      platformStyle = PlatformTextStyle(
     includeFontPadding = false
   ),
)

Run Code Online (Sandbox Code Playgroud)

https://android-developers.googleblog.com/2022/05/whats-new-in-jetpack-compose.html

尝试一下,可能有帮助吗?顺便说一句,如果您注意到 PlatformTextStyle 已“弃用”,这只是想告知这是一个兼容性 API。我们从 1.5 及更高版本开始删除了更新的 compose 版本中的弃用警告。


小智 8

根据https://issuetracker.google.com/issues/171394808,这似乎是当前 JetPack Compose 的限制之一。

这对我的应用程序来说也是一个破坏因素,因为使用的字体严重依赖于includeFontPadding. 对于当前的解决方法,我创建了一个 CoreText,将 TextView 包装在我的撰写中。

这是我的包装器的示例,它并不完美,但它可以满足我当前的用例:

@Composable
fun CoreText(
    text: String,
    modifier: Modifier = Modifier,
    color: Color = Color.Unspecified,
    textDecoration: TextDecoration? = null,
    textAlign: TextAlign? = null,
    overflow: TextOverflow = TextOverflow.Clip,
    maxLines: Int = Int.MAX_VALUE,
    style: TextStyle = Typography.body2,
    onClick: (() -> Unit)? = null,
) {
    AndroidView(
        modifier = modifier,
        factory = { context ->
            TextView(context)
        },
        update = {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                it.setTextAppearance(style.fontWeight.toStyle())
            } else {
                it.setTextAppearance(it.context, style.fontWeight.toStyle())
            }

            if (overflow == TextOverflow.Ellipsis) {
                it.ellipsize = TextUtils.TruncateAt.END
            }

            if (textDecoration != null) {
                it.paintFlags = when (textDecoration) {
                    TextDecoration.Underline -> {
                        Paint.UNDERLINE_TEXT_FLAG
                    }
                    TextDecoration.LineThrough -> {
                        Paint.STRIKE_THRU_TEXT_FLAG
                    }
                    else -> 0
                }
            }

            if (onClick != null) {
                it.setOnClickListener { onClick.invoke() }
            }

            if (color != Color.Unspecified || style.color != Color.Unspecified) {
                it.setTextColor(if (color == Color.Unspecified) style.color.toArgb() else color.toArgb())
            }

            it.textSize = style.fontSize.value
            it.text = text
            it.background = ColorDrawable(style.background.toArgb())
            it.maxLines = maxLines
            it.includeFontPadding = false
            it.textAlignment = textAlign?.toStyle() ?: style.textAlign.toStyle()
        }
    )
}

// Replace with your style
fun FontWeight?.toStyle(): Int {
    return when (this) {
        FontWeight.Bold -> R.style.TextStyle_Bold
        FontWeight.Normal -> R.style.TextStyle_Regular
        FontWeight.Medium, FontWeight.SemiBold -> R.style.TextStyle_Medium
        else -> -1
    }
}

fun TextAlign?.toStyle(): Int {
    return when (this) {
        TextAlign.Left -> TEXT_ALIGNMENT_TEXT_START
        TextAlign.Right -> TEXT_ALIGNMENT_TEXT_END
        TextAlign.Center -> TEXT_ALIGNMENT_CENTER
        TextAlign.Start -> TEXT_ALIGNMENT_TEXT_START
        TextAlign.End -> TEXT_ALIGNMENT_TEXT_END
        else -> -1
    }
}
Run Code Online (Sandbox Code Playgroud)


Ric*_*per -1

刚刚解决了同样的问题。

Box(contentAlignment = Alignment.Center){
       Text(
                text = "OK"
                textAlign = TextAlign.Center
        )
}
Run Code Online (Sandbox Code Playgroud)