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

Jetpack Compose 中如何为省略的 Text 组件添加 See More 展开标签

实现方案

你可以通过判断文本溢出状态、拼接注解字符串的方式实现需求,具体实现如下:

  • 声明两个状态变量:isExpanded控制文本是否展开,isTextOverflow记录当前文本是否真的超出了限制行数,避免短文本也展示See More提示
  • 借助Text组件的onTextLayout回调,拿到布局结果判断文本是否存在视觉溢出
  • 文本溢出且未展开时,拼接原文本、省略号和带特殊样式的「See More」内容;展开或无溢出时直接展示完整原文本
  • 给文本添加点击事件,仅在文本存在溢出时响应点击切换展开状态

完整实现代码

import androidx.compose.foundation.clickable
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.text.withStyle

@Composable
fun ExpandableText(
    text: String,
    maxLines: Int = 1,
    seeMoreText: String = "See More",
    seeMoreColor: Color = Color.Blue
) {
    var isExpanded by remember { mutableStateOf(false) }
    var isTextOverflow by remember { mutableStateOf(false) }

    val displayText = remember(text, isExpanded, isTextOverflow) {
        when {
            isExpanded || !isTextOverflow -> buildAnnotatedString { append(text) }
            else -> buildAnnotatedString {
                // 简单截取预留省略号+See More的位置,如需精准截断可通过TextLayoutResult计算精确截断索引
                val truncatedText = text.take(text.length - (seeMoreText.length + 5))
                append(truncatedText)
                append("… ")
                withStyle(style = SpanStyle(color = seeMoreColor)) {
                    append(seeMoreText)
                }
            }
        }
    }

    Text(
        text = displayText,
        maxLines = if (isExpanded) Int.MAX_VALUE else maxLines,
        overflow = TextOverflow.Ellipsis,
        modifier = Modifier.clickable(enabled = isTextOverflow) {
            isExpanded = !isExpanded
        },
        onTextLayout = { layoutResult ->
            if (!isExpanded) {
                isTextOverflow = layoutResult.hasVisualOverflow
            }
        }
    )
}

使用方法

直接替换你原来的Text组件即可,示例:

ExpandableText(
    text = "this is some sample text that is long and so it is ellipsized",
    maxLines = 1
)

优化提示

如果需要避免在文字中间截断、适配不同字号字体的精准截断效果,可以在onTextLayout回调中通过layoutResult.getLineEnd(maxLines - 1)拿到限制行数最后一个字符的索引,再基于这个值计算精确的截断位置即可。

内容的提问来源于stack exchange,提问作者rohan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 22:57:03