我們一般給文字加下劃線是這樣加的
const Text(
text,
style: TextStyle(
decoration: TextDecoration.underline, // 添加下劃線
decorationColor: Colors.black, // 設(shè)置下劃線顏色
decorationThickness: 2, // 設(shè)置下劃線的粗細(xì)
),
)

image.png
當(dāng)文字中有中文 英文的時(shí)候,在Android中顯示效果有些問題,下劃線沒有對(duì)齊。在iOS下到時(shí)沒有這個(gè)問題。
為此寫個(gè)簡單的Widget來解決這個(gè)小問題
multiline_underline_text.dart
import 'package:flutter/material.dart';
class MultilineUnderlineText extends StatelessWidget {
final String text;
final TextStyle? textStyle;
final Color underlineColor;
final double underlineThickness;
final double? underlinePadding;
final TextAlign textAlign;
const MultilineUnderlineText({
super.key,
required this.text,
this.textStyle,
this.underlineColor = Colors.black,
this.underlineThickness = 1.0,
this.underlinePadding = 2.0,
this.textAlign = TextAlign.left,
});
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
return CustomPaint(
painter: _UnderlinePainter(
text: text,
textStyle: textStyle ?? Theme.of(context).textTheme.bodyMedium!,
underlineColor: underlineColor,
underlineThickness: underlineThickness,
underlinePadding: underlinePadding ?? 2.0,
maxWidth: constraints.maxWidth,
textAlign: textAlign,
),
child: Text(
text,
style: textStyle,
textAlign: textAlign,
),
);
},
);
}
}
class _UnderlinePainter extends CustomPainter {
final String text;
final TextStyle textStyle;
final Color underlineColor;
final double underlineThickness;
final double underlinePadding;
final double maxWidth;
final TextAlign textAlign;
_UnderlinePainter({
required this.text,
required this.textStyle,
required this.underlineColor,
required this.underlineThickness,
required this.underlinePadding,
required this.maxWidth,
required this.textAlign,
});
@override
void paint(Canvas canvas, Size size) {
final textPainter = TextPainter(
text: TextSpan(text: text, style: textStyle),
textDirection: TextDirection.ltr,
textAlign: textAlign,
maxLines: null,
);
textPainter.layout(maxWidth: maxWidth);
final lineMetrics = textPainter.computeLineMetrics();
final Paint paint = Paint()
..color = underlineColor
..strokeWidth = underlineThickness
..style = PaintingStyle.stroke;
for (var line in lineMetrics) {
double startX = 0;
double width = line.width;
// 處理文本對(duì)齊
switch (textAlign) {
case TextAlign.center:
startX = (size.width - width) / 2;
break;
case TextAlign.right:
startX = size.width - width;
break;
case TextAlign.left:
default:
startX = 0;
break;
}
// 調(diào)整下劃線位置,考慮下延字母
// 使用字體大小的比例來計(jì)算偏移量
final fontSize = textStyle.fontSize ?? 14.0;
final descenderOffset = fontSize * 0.2; // 增加偏移量以適應(yīng)下延字母
final underlineY = line.baseline + underlinePadding + descenderOffset;
canvas.drawLine(
Offset(startX, underlineY),
Offset(startX + width, underlineY),
paint,
);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
顯示效果:
Android

image.png
iOS

9a42fefc2e66c2069c4a4b6b4f8d59ea.png