You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Jetpack Compose中实现文本与尾部图标随内容换行的drawableEnd等效效果

Jetpack Compose中实现文本与尾部图标随内容换行的drawableEnd等效效果

哈哈,这个需求我太懂了!之前用TextView的时候靠android:drawableEnd就能轻松实现文本和图标绑定换行,刚转Compose的时候也踩过Row和FlowRow的坑,跟你遇到的情况一模一样——要么图标钉在右边不跟着走,要么直接被挤到下一行,完全不是想要的效果。

其实Compose里有专门的方案来实现这种“文本+内联图标”的绑定布局,就是用AnnotatedString配合TextinlineContent参数,完美复刻drawableEnd的效果,让图标和文本完全绑定成一个整体,空间不够时跟着文本最后一行一起换行。

直接上代码示例,一看就懂:

首先定义内联图标的布局配置,给图标预留合适的占位空间,确保文本布局时不会和图标重叠:

// 定义内联图标配置
val endIconContent = mapOf(
    "textEndIcon" to InlineTextContent(
        Placeholder(
            width = 20.sp, // 图标宽度
            height = 20.sp, // 图标高度
            placeholderVerticalAlign = PlaceholderVerticalAlign.TextCenter // 图标与文本垂直居中对齐
        )
    ) {
        // 这里绘制你需要的图标
        Icon(
            imageVector = Icons.Default.Star,
            contentDescription = "尾部图标",
            modifier = Modifier.size(20.sp),
            tint = Color.Gray
        )
    }
)

然后构建带有图标标记的文本内容,把图标插入到文本的末尾:

// 构建带内联图标的文本
val bindedText = buildAnnotatedString {
    append("这是一段很长很长的文本,当空间不够的时候,尾部的图标会跟着文本的最后一行一起换行,而不是固定在右边或者单独跑到下一行")
    // 插入之前定义的内联图标标记
    appendInlineContent("textEndIcon")
}

最后用Text组件渲染这个带内联图标的文本就行:

Text(
    text = bindedText,
    inlineContent = endIconContent,
    modifier = Modifier.width(200.dp) // 模拟窄屏幕空间,方便看换行效果
)

为啥之前的方法不行呢?我也给你理一理:

  • RowModifier.weight(1f):Row是强制横向布局,weight让文本占满剩余横向空间,图标会一直固定在Row的最右侧,不管文本换多少行,图标都不会跟着走,完全不符合“绑定换行”的需求。
  • FlowRow:FlowRow是把每个子元素当成独立的布局单元,当横向空间不够时,会把后面的元素(也就是图标)挤到下一行,而不是让图标附着在文本的最后一行末尾,所以也达不到drawableEnd的效果。

另外你还可以根据需求调整细节:比如修改PlaceholderplaceholderVerticalAlign属性,改成PlaceholderVerticalAlign.Baseline让图标和文本基线对齐;或者调整Placeholder和Icon的大小,确保图标和文本的比例协调。

内容来源于stack exchange

火山引擎 最新活动