You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 18:45:03