Jetpack Compose,居中文本而不填充字体? [英] Jetpack Compose, centering text without font padding?
问题描述
我在 Jetpack Compose alpha-11 版本中遇到垂直居中文本的问题.看来我的字体有大量的填充,我无法找到禁用它的方法.据我所知,这之前只出现过一次,
代码如下:
列(verticalArrangement =Arrangement.Center){文本(text = "我们走吧",颜色 = Color.White,字体大小 = 120.sp,fontFamily = oswaldLightFontFamily(),textAlign = TextAlign.Center,修饰符 = Modifier.background(Color.Blue))}
您希望放置它的参数 -- verticalArrangement
和 textAlign
-- 在这里不做任何事情,但我将它们包括在内以证明我已经尝试过.
到目前为止,我的解决方法是使用 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屋!