将 Flutter 文本字段背景制作为笔记本样式(内衬文本字段)

问题描述 投票:0回答:1

我想在我的应用程序中制作一个笔记本页面,如下图所示,我不需要自定义绘画或 SVG 或任何类型的照片,当我滚动页面时,线条仍在文本下方,是否有任何自定义带有线条背景的文本字段可以使用吗?

flutter dart textfield
1个回答
0
投票

您必须用

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
设置为
useMaterial3: false
时才有效。我还没有弄清楚如何正确测量 Material3 文本。

© www.soinside.com 2019 - 2024. All rights reserved.