Compose中letterSpacing引发文本截断:TextAlign.End+Ellipsis场景的解决方法
Jetpack Compose中Text组件带letterSpacing、TextAlign.End和Ellipsis时文本截断的修复方法
问题复现
在Jetpack Compose开发中,当给Text组件同时设置TextAlign.End、TextOverflow.Ellipsis,且在TextStyle中配置letterSpacing时,会出现文本被异常截断的问题。复现代码如下:
val textStyleWithoutLetterSpacing = TextStyle() val textStyleWithLetterSpacing = TextStyle(letterSpacing = 1.sp) @Composable fun Sample() { Column { Text( text = "1234567890 1234567890 1234567890", textAlign = TextAlign.End, overflow = TextOverflow.Ellipsis, maxLines = 1, style = textStyleWithoutLetterSpacing ) Text( text = "1234567890 1234567890 1234567890", textAlign = TextAlign.End, overflow = TextOverflow.Ellipsis, maxLines = 1, style = textStyleWithLetterSpacing ) } }
现象:未设置letterSpacing的文本能正常显示末尾省略号,而添加了letterSpacing的文本会被过度截断,甚至无法完整显示省略号。
修复方案
方案1:升级Jetpack Compose版本
该问题属于Compose官方的布局计算bug,在Compose 1.4.0及以上稳定版中已被修复。直接将项目的Compose依赖升级到最新稳定版本,即可解决此问题。
方案2:添加偏移padding抵消计算误差
如果暂时无法升级版本,可以给Text组件添加一个微小的paddingEnd,抵消letterSpacing带来的布局计算偏差:
Text( text = "1234567890 1234567890 1234567890", textAlign = TextAlign.End, overflow = TextOverflow.Ellipsis, maxLines = 1, style = textStyleWithLetterSpacing, modifier = Modifier.paddingEnd(textStyleWithLetterSpacing.letterSpacing * 0.5f) )
这里的0.5f是经验值,可根据实际使用的letterSpacing大小微调。
方案3:使用BasicText组件替代Text
BasicText提供了更底层的文本测量控制,能规避Text组件的布局计算问题:
@Composable fun FixedEndAlignedText( text: String, modifier: Modifier = Modifier, letterSpacing: TextUnit = 0.sp, maxLines: Int = 1, baseStyle: TextStyle = TextStyle() ) { val textMeasurer = rememberTextMeasurer() BasicText( text = text, modifier = modifier, style = baseStyle.copy(letterSpacing = letterSpacing), maxLines = maxLines, overflow = TextOverflow.Ellipsis, textAlign = TextAlign.End, textMeasurer = textMeasurer ) } // 使用示例 @Composable fun SampleFixed() { Column { // 原无letterSpacing的Text保留 Text( text = "1234567890 1234567890 1234567890", textAlign = TextAlign.End, overflow = TextOverflow.Ellipsis, maxLines = 1, style = textStyleWithoutLetterSpacing ) // 使用修复后的组件 FixedEndAlignedText( text = "1234567890 1234567890 1234567890", letterSpacing = 1.sp, maxLines = 1, baseStyle = TextStyle() ) } }
问题原因
早期Compose版本中,Text组件在计算右对齐文本的省略位置时,没有将letterSpacing带来的额外字符间距纳入布局边界计算,导致系统错误地判断文本超出范围,从而过度截断内容。
内容的提问来源于stack exchange,提问作者Almir Burnashev
相关产品推荐
相关产品推荐

