您必须用
TextField
小部件包装您自己的 CustomPaint
。首先,创建一个 TextPainter
,其 style
与您的 TextField
匹配,并以非零宽度调用 layout
。
final textPainter = TextPainter(
text: TextSpan(
text: ' ',
style: style,
),
textDirection: TextDirection.ltr,
textScaler: MediaQuery.textScalerOf(context),
)..layout(maxWidth: 12.0);
这个
TextPainter
将使您能够访问以正确的偏移绘制线条所需的两个值。
/// The entire height of a line
textPainter.height
/// The distance from the top of a line to the bottom of a character on that line
textPainter.computeDistanceToActualBaseline(TextBaseline.alphabetic)
这些可以组合起来在每一行文本下绘制:
class LinePainter extends CustomPainter {
final double distanceToBaseline;
final double lineHeight;
/// If your `TextField` has any content-padding,
/// the top value will need to be added here
final double offsetY;
LinePainter({
required this.distanceToBaseline,
required this.lineHeight,
this.offsetY = 0,
});
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()..color = Colors.black;
final intialOffset = offsetY + distanceToBaseline;
for (double y = intialOffset; y < size.height; y = y + lineHeight) {
canvas.drawLine(Offset(0, y), Offset(size.width, y), paint);
}
}
@override
bool shouldRepaint(LinePainter oldDelegate) {
if (oldDelegate.distanceToBaseline != distanceToBaseline ||
oldDelegate.lineHeight != lineHeight ||
oldDelegate.offsetY != offsetY) {
return true;
}
return false;
}
}
全部合并:
CustomPaint(
painter: LinePainter(
offsetY: 0, // Adjust this value with your `TextField` content-padding-top
lineHeight: textPainter.height,
distanceToBaseline: textPainter.computeDistanceToActualBaseline(TextBaseline.alphabetic),
),
child: TextField(style: textStyle),
),
注意:此示例仅在您的
设置为Theme
时才有效。我还没有弄清楚如何正确测量 Material3 文本。useMaterial3: false