SwiftUI中如何为多行动态文本创建自定义样式下划线?
实现多行TextView的自定义行下划线样式
针对你需要的多行文本每行添加自定义下划线(厚度为单行高度一半、带垂直偏移)的需求,这里提供Jetpack Compose下的可行方案——通过文本布局测量+自定义绘制实现:
核心思路
利用TextMeasurer获取文本的逐行布局信息,在drawBehind修饰符中为每行单独绘制符合要求的下划线,既支持动态文本,也不会出现背景覆盖整个视图的问题。
代码实现
@Composable fun CustomUnderlineText( text: String, modifier: Modifier = Modifier, textStyle: TextStyle = TextStyle.Default, underlineThicknessRatio: Float = 0.5f, // 下划线厚度占单行高度的比例 underlineVerticalOffset: Dp = 4.dp, // 下划线相对于文本行底部的垂直偏移 underlineColor: Color = textStyle.color.copy(alpha = 0.8f) ) { val textMeasurer = rememberTextMeasurer() val density = LocalDensity.current // 将dp转为像素,统一测量单位 val underlineThicknessPx = with(density) { (textStyle.lineHeight * underlineThicknessRatio).toPx() } val underlineOffsetPx = with(density) { underlineVerticalOffset.toPx() } BasicText( text = text, modifier = modifier.drawBehind { // 测量当前文本的布局结果 val layoutResult = textMeasurer.measure( text = AnnotatedString(text), style = textStyle, constraints = constraints ) // 遍历每一行文本,绘制对应下划线 layoutResult.layoutInput.layoutLines.forEach { lineIndex -> val lineBottom = layoutResult.getLineBottom(lineIndex) val lineLeft = layoutResult.getLineLeft(lineIndex) val lineRight = layoutResult.getLineRight(lineIndex) drawRoundRect( color = underlineColor, topLeft = Offset(lineLeft, lineBottom + underlineOffsetPx), size = Size(lineRight - lineLeft, underlineThicknessPx), cornerRadius = CornerRadius(underlineThicknessPx / 2) // 可选:添加圆角 ) } }, style = textStyle ) }
使用示例
CustomUnderlineText( text = "这是一段动态的多行文本示例,每一行都会带有自定义的下划线样式,厚度是单行高度的一半,还可以调整垂直偏移量。", textStyle = TextStyle( fontSize = 16.sp, lineHeight = 24.sp, color = Color.Black ), underlineVerticalOffset = 2.dp, underlineColor = Color(0xFF6200EE) )
方案优势
- 逐行精准绘制:只会为每行文本添加下划线,不会覆盖整个文本视图区域
- 完全自定义:可灵活调整下划线厚度比例、垂直偏移、颜色、圆角等参数
- 支持动态文本:文本内容变化时,布局测量会自动更新,下划线位置同步调整
- 无需拆分文本:即使是动态字符串,也不需要手动拆分为多个文本组件
内容的提问来源于stack exchange,提问作者kazzer
相关产品推荐
相关产品推荐

