首页 > 解决方案 > 颤动中的单个文本字段可以具有可变的行高吗?

问题描述

我正在实现一个简单的富文本编辑器,它使用识别基本降价语法的文本编辑控制器呈现文本,我将在下面链接一些代码。

一切正常,我遇到的唯一问题是当文本样式需要更大的行高时,例如# h1应该呈现为标题并因此需要更大的行高与前一行重叠,如您在下面的截图。

到目前为止,我还无法根据正在显示的文本的样式在 TextView 变量中设置行高,这在 Flutter TextView 中是否可以实现?

这是我的文本编辑控制器的片段和详细说明我的问题的屏幕截图。

在此处输入图像描述

import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

class AddNotePage extends StatelessWidget {
  final TextEditingController _controller = MarkdownTextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Add Note'),
      ),
      body: GestureDetector(
        onVerticalDragDown: (_) {
          FocusScopeNode currentFocus = FocusScope.of(context);

          if (!currentFocus.hasPrimaryFocus) {
            currentFocus.unfocus();
          }
        },
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            Expanded(
              child: TextField(
                style: defaultTextStyle,
                controller: _controller,
                decoration: InputDecoration(
                  hintText: "Insert your message",
                  border: UnderlineInputBorder(
                    borderSide: BorderSide.none,
                  ),
                ),
                scrollPadding: EdgeInsets.all(20.0),
                keyboardType: TextInputType.multiline,
                maxLines: null,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

const Map<String, TextStyle> defaultMarkdownStyleMap = {
  r'^# .*?$': TextStyle(
    fontWeight: FontWeight.bold,
    fontSize: 50,
  ),
  r'^## .*?$': TextStyle(
    fontWeight: FontWeight.bold,
    fontSize: 40,
  ),
  r'^### .*?$': TextStyle(
    fontWeight: FontWeight.bold,
    fontSize: 30,
  ),
  r'__(.*?)\__': TextStyle(fontStyle: FontStyle.italic, fontSize: 20),
  r'~~(.*?)~~': TextStyle(decoration: TextDecoration.lineThrough, fontSize: 20),
  r'\*\*(.*?)\*\*': TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
};

const TextStyle defaultTextStyle = TextStyle(fontSize: 20);

class MarkdownTextEditingController extends TextEditingController {
  final Map<String, TextStyle> styleMap;
  final Pattern pattern;

  MarkdownTextEditingController({this.styleMap = defaultMarkdownStyleMap})
      : pattern = RegExp(
            styleMap.keys.map((key) {
              return key;
            }).join('|'),
            multiLine: true);

  @override
  TextSpan buildTextSpan(
      {required BuildContext context,
      TextStyle? style,
      required bool withComposing}) {
    final List<InlineSpan> children = [];

    text.splitMapJoin(
      pattern,
      onMatch: (Match match) {
        TextStyle? markdownStyle = styleMap[styleMap.keys.firstWhere(
          (e) {
            return RegExp(e).hasMatch(match[0]!);
          },
        )];

        children.add(TextSpan(
          text: match[0],
          style: style!.merge(markdownStyle),
        ));
        return "";
      },
      onNonMatch: (String text) {
        children
            .add(TextSpan(text: text, style: style!.merge(defaultTextStyle)));
        return "";
      },
    );

    return TextSpan(style: style, children: children);
  }
}

标签: flutterdarttextviewflutter-layout

解决方案


我找到了解决方案。我需要做的就是使用strutStyleTextField 的属性。

正如文档所述:

用于垂直布局的支柱样式。

StrutStyle 用于建立可预测的垂直布局。由于字体可能会因用户输入和字体回退而有所不同,因此默认启用 StrutStyle.forceStrutHeight 以将所有行锁定到由样式提供的基本 TextStyle 的高度。这可确保键入的文本适合分配的空间。


推荐阅读