Jetpack Compose,居中文本而不填充字体? [英] Jetpack Compose, centering text without font padding?

查看:79
本文介绍了Jetpack Compose,居中文本而不填充字体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Jetpack Compose alpha-11 版本中遇到垂直居中文本的问题.看来我的字体有大量的填充,我无法找到禁用它的方法.据我所知,这之前只出现过一次,

代码如下:

 列(verticalArrangement =Arrangement.Center){文本(text = "我们走吧",颜色 = Color.White,字体大小 = 120.sp,fontFamily = oswaldLightFontFamily(),textAlign = TextAlign.Center,修饰符 = Modifier.background(Color.Blue))}

您希望放置它的参数 -- verticalArrangementtextAlign -- 在这里不做任何事情,但我将它们包括在内以证明我已经尝试过.

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

有人遇到过这种情况吗?

解决方案

根据 https://issuetracker.google.com/issues/171394808,看来这是目前JetPack Compose的局限性之一.

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

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

@Composable有趣的核心文本(文本:字符串,修饰符:修饰符 = 修饰符,颜色:颜色 = 颜色.未指定,文本装饰:文本装饰?= 空,文本对齐:文本对齐?= 空,溢出:TextOverflow = TextOverflow.Clip,maxLines: Int = Int.MAX_VALUE,样式:TextStyle = Typography.body2,onClick: (() -> 单位)?= 空,){安卓视图(修饰符 = 修饰符,工厂 = { 上下文 ->文本视图(上下文)},更新 = {如果 (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {it.setTextAppearance(style.fontWeight.toStyle())} 别的 {it.setTextAppearance(it.context, style.fontWeight.toStyle())}如果(溢出== TextOverflow.Ellipsis){it.ellipsize = TextUtils.TruncateAt.END}如果(文本装饰!= null){it.paintFlags = when (textDecoration) {TextDecoration.Underline ->{Paint.UNDERLINE_TEXT_FLAG}TextDecoration.LineThrough ->{Paint.STRIKE_THRU_TEXT_FLAG}否则 ->0}}如果(点击!= 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.valueit.text = 文本it.background = ColorDrawable(style.background.toArgb())it.maxLines = maxLinesit.includeFontPadding = falseit.textAlignment = textAlign?.toStyle() ?: style.textAlign.toStyle()})}//替换成你的风格有趣的 FontWeight?.toStyle(): Int {返回时(这){FontWeight.Bold ->R.style.TextStyle_BoldFontWeight.Normal ->R.style.TextStyle_RegularFontWeight.Medium, FontWeight.SemiBold ->R.style.TextStyle_Medium否则 ->-1}}有趣的 TextAlign?.toStyle(): Int {返回时(这){TextAlign.Left ->TEXT_ALIGNMENT_TEXT_STARTTextAlign.Right ->TEXT_ALIGNMENT_TEXT_ENDTextAlign.Center ->TEXT_ALIGNMENT_CENTERTextAlign.Start ->TEXT_ALIGNMENT_TEXT_STARTTextAlign.End ->TEXT_ALIGNMENT_TEXT_END否则 ->-1}}

I'm struggling with vertically centering text in Jetpack Compose version alpha-11. It appears that my font has a significant amount of padding and I'm unable to find a way to disable it. This has come up only once before on SO, as far as I can tell, here, but their answer of using a constraint layout seems to suggest that they simply positioned it absolutely, which isn't exactly a solution as much as a workaround, and something I'd like to avoid.

You can see it clearly in the screenshot below.

The code for that looks like this:

                   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)
                        )
                    }

The arguments you would expect to position it -- verticalArrangement and textAlign -- do not do anything here but I'm including them to demonstrate what I've tried.

My workaround so far has been to use Modifier.graphicsLayer(translationY = -25f) to shift it up but that seems like a terrible hack for something that should be so straightforward. It appears that in classic Android layouts, one could set android:includeFontPadding="false" and that would bypass this behavior but there doesn't seem to be a similar option in Jetpack Compose.

Anyone encounter this?

解决方案

According to https://issuetracker.google.com/issues/171394808, It seems this is one of the limitations of the current JetPack Compose.

This is also deal breaker for my app because the font used rely heavily with the includeFontPadding. For current workaround, I create a CoreText that wraps TextView inside my compose.

Here's example of my wrapper, its not perfect but it does the job for my current use case:

@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
    }
}

这篇关于Jetpack Compose,居中文本而不填充字体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆