如何在Jetpack Compose的Text组件中实现文本中间省略效果
Jetpack Compose Text 组件中间省略效果实现方案
原生Text组件提供的TextOverflow枚举仅包含Clip、Ellipsis、Visible三种模式,其中Ellipsis仅支持末尾省略,没有内置中间省略的能力,可通过以下两种方案实现需求:
方案1:自适应宽度的通用实现
该方案会根据文本样式、组件可用宽度自动计算截取长度,适配所有场景,可直接复用扩展函数:
/** * 生成适配组件宽度的中间省略文本 * @param originalText 原始文本内容 * @param maxWidth Text组件的最大可用宽度 * @param textStyle Text使用的文本样式,用于宽度测量 * @param keepEndCharCount 尾部固定保留的字符数,默认保留8位 */ @Composable fun rememberMiddleEllipsisText( originalText: String, maxWidth: Dp, textStyle: TextStyle, keepEndCharCount: Int = 8 ): String { val density = LocalDensity.current return remember(originalText, maxWidth, textStyle, density) { if (originalText.length <= keepEndCharCount + 4) return@remember originalText val endPart = originalText.takeLast(keepEndCharCount) val placeholder = "..." // 从最长前缀开始逐步缩短,直到拼接后的文本不超出宽度 for (prefixLen in (originalText.length - keepEndCharCount) downTo 1) { val testText = originalText.take(prefixLen) + placeholder + endPart val textWidth = with(density) { TextPainter( text = AnnotatedString(testText), style = textStyle, density = this ).run { layout(Int.MAX_VALUE) width.toDp() } } if (textWidth <= maxWidth) return@remember testText } // 极端宽度场景降级为省略号加尾部内容 placeholder + endPart } }
使用示例
Box(modifier = Modifier.width(200.dp)) { val rawText = "4gh45g43h98sdf7g6h5j4k3l2bh4bh6b64" val textStyle = TextStyle(fontSize = 16.sp) // 传入Text组件的最大宽度和样式 val showText = rememberMiddleEllipsisText( originalText = rawText, maxWidth = 200.dp, textStyle = textStyle ) Text( text = showText, style = textStyle, maxLines = 1 ) }
方案2:固定长度截取(等宽字符场景专属)
如果文本是哈希值、数字字母组合这类等宽字符,可以直接按固定长度截取,不需要测量,性能更高:
// 扩展函数:中间省略,默认前后各保留8位 fun String.middleEllipsis(keepStart: Int = 8, keepEnd: Int = 8): String { return if (length <= keepStart + keepEnd + 3) { this } else { "${take(keepStart)}...${takeLast(keepEnd)}" } } // 使用方式 Text( text = "4gh45g43h98sdf7g6h5j4k3l2bh4bh6b64".middleEllipsis(), maxLines = 1 )
最终展示效果为你需要的4gh45g43h...bh4bh6b64。
内容的提问来源于stack exchange,提问作者Rafael
相关产品推荐
相关产品推荐

