Flutter - 如何实现多行下划线TextField

5
我想实现以下包含多行文本框和每行下划线的UI。有什么想法如何实现吗?

enter image description here

Expanded(
child: Padding(
    padding: const EdgeInsets.symmetric(horizontal: 5.0),
    child: TextField(
        controller: problemItem.titleController,
        decoration: const InputDecoration(
                                border: InputBorder.none),
        keyboardType: TextInputType.multiline,
        minLines: 3,
        maxLines: 100,
        )
    ),
),
3个回答

4

您可以使用StackTextField堆叠成多行。您需要将TextFieldexpands属性设置为true,以便使其从一开始就扩展到完整的三行宽度。
我实现了一个类似于您试图创建的TextField

Stack(
  children: [
    for (int i = 0; i < 3; i++)
      Container(
        width: double.infinity,
        margin: EdgeInsets.only(
          top: 4 + (i + 1) * 28,
          left: 15,
          right: 15,
        ),
        height: 1,
        color: Colors.black,
      ),
    const SizedBox(
      height: 97,
      child: Padding(
        padding: EdgeInsets.symmetric(horizontal: 15),
        child: TextField(
          decoration: InputDecoration(border: InputBorder.none),
          cursorHeight: 22,
          style: TextStyle(
            fontSize: 20.0,
          ),
          keyboardType: TextInputType.multiline,
          expands: true,
          maxLines: null,
        ),
      ),
    ),
  ],
),

结果:
在这里输入图片描述

1

这只是一个简单的示例,演示了如何在一般情况下在文本更改时生成下划线。如果下划线位置不在您想要的位置,则仍需要调整屏幕上的输出行为。

查看更多关于高度属性的信息

enter image description here

如果您想分配一个固定行数的文本框,可以尝试下面的小部件:
由于需要使用fontSize和height来计算行数,因此需要stylecontroller用于监控文本更改。
在initState中使用textPainter模拟文本行为并计算将显示的文本行数。
class UnderlineTextField extends StatefulWidget {
  const UnderlineTextField({
    required this.style,
    this.controller,
    this.maxLines = 3,
    Key? key,
  }) : super(key: key);

  final TextEditingController? controller;
  final int? maxLines;
  final TextStyle style;

  @override
  State<UnderlineTextField> createState() => _UnderlineTextFieldState();
}

class _UnderlineTextFieldState extends State<UnderlineTextField> {
  double maxWidth = 0;
  int numberOfLines = 1;

  @override
  void initState() {
    /// Calculate numberOfLines
    widget.controller?.addListener(() {
      final text = widget.controller?.text ?? '';
      final textPainter = TextPainter(
        text: TextSpan(text: text, style: widget.style),
        maxLines: widget.maxLines,
        textDirection: TextDirection.ltr,
      );

      textPainter.layout(maxWidth: maxWidth);
      setState(() {
        numberOfLines = textPainter.computeLineMetrics().length;
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    final fontSize = widget.style.fontSize ?? 12;
    final textHeight = fontSize * (widget.style.height ?? 1);

    return LayoutBuilder(
      builder: (_, constrinat) {
        maxWidth = constrinat.maxWidth;
        return Stack(
          children: [
            TextField(
              style: widget.style,
              controller: widget.controller,
              decoration: const InputDecoration(
                isDense: true,
                border: InputBorder.none,
              ),
              maxLines: widget.maxLines,
            ),
            Positioned.fill(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: List.generate(
                  numberOfLines,
                  (index) => Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      SizedBox(height: textHeight - 1),
                      const Divider(height: 1, thickness: 1),
                    ],
                  ),
                ),
              ),
            ),
          ],
        );
      },
    );
  }
}

我希望能够得到更多关于这个的解释,也许还有UnderLineTextField小部件的完整示例。 - MaylorTaylor
原始答案很久以前发布了。我已经更新并简化了小部件。 - yellowgray

0
Stack(
          children: [
            for (int i = 0; i < 4; i++)
              Container(
                margin: EdgeInsets.only(
                  top: 4 + (i + 1) * 28,
                  left: 15,
                  right: 15,
                ),
                height: 2,
                color: Colors.black,
              ),
            const Padding(
              padding: EdgeInsets.symmetric(horizontal: 15),
              child: TextField(
                decoration: InputDecoration(border: InputBorder.none),
                style: TextStyle(
                  fontSize: 20.0,
                ),
                keyboardType: TextInputType.multiline,
                expands: true,
                maxLines: null,
              ),
            ),
          ],
        ),

目前你的回答不够清晰,请[编辑]以添加更多细节,帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接