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
相关产品推荐
相关产品推荐

