首页 > 解决方案 > 强制容器内的小部件将自身限制为一行

问题描述

我对 Flutter 比较陌生,并且有一个我觉得应该很容易解决的布局问题。我正在尝试将 a MarkdownBody(包含一些 HTML 文本)呈现为 a 的标题ListTile。如果标题太长,就会溢出。如果我可以使用Text小部件而不是 aMarkdownBody那么解决方案将非常简单:使用maxLines: 1overflow: TextOverflow.ellipsis. 但由于标题包含我正在使用的 HTML MarkdownBody,所以这就是我创建标题的方式:

   return new Container(
      height: 25.0,
      child: new Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          new Expanded(
            child: new MarkdownBody(
              data: converted,
              styleSheet: MarkdownStyleSheet(
                p: textStyle,
                strong: TextStyle(fontWeight: FontWeight.bold),
              ),
            ),
          )
        ],
      ),
    );

这就是它的样子:

在此处输入图像描述

该搜索结果中的每一行都ListTile包含在 aContainer中,其标题和副标题的创建如上所示。我要做的是确保如果文本太长,标题和副标题都被切断。我尝试将MarkdownBody内部各种布局小部件包装起来;例如Container, SizedBox, Rowwith Expanded, 但无法解决溢出问题。

我怎样才能做到这一点?

标签: flutterflutter-layout

解决方案


理想的解决方案是克隆原始包并在其中添加一个额外的小部件,以便您可以在和/或设置为限制生成的子项时提供overflow/maxLines属性并中断/扩展解析逻辑。overflowmaxLines

假设降价的长度对于您的传入数据来说是最小的,您可以MarkdownWidget在自己的项目中进行扩展,然后像这样破解它(节省您编写自己的解析器或不得不克隆另一个项目):

import 'dart:io';

import 'package:flutter/widgets.dart';
import 'package:flutter_markdown/flutter_markdown.dart';

class SingleLineMarkdownBody extends MarkdownWidget {
  final TextOverflow overflow;
  final int maxLines;

  const SingleLineMarkdownBody(
      {Key key,
      String data,
      MarkdownStyleSheet styleSheet,
      SyntaxHighlighter syntaxHighlighter,
      MarkdownTapLinkCallback onTapLink,
      Directory imageDirectory,
      this.overflow,
      this.maxLines})
      : super(
          key: key,
          data: data,
          styleSheet: styleSheet,
          syntaxHighlighter: syntaxHighlighter,
          onTapLink: onTapLink,
          imageDirectory: imageDirectory,
        );

  @override
  Widget build(BuildContext context, List<Widget> children) {
    var richText = _findWidgetOfType<RichText>(children.first);
    if (richText != null) {
      return RichText(
        text: richText.text,
        textAlign: richText.textAlign,
        textDirection: richText.textDirection,
        softWrap: richText.softWrap,
        overflow: this.overflow,
        textScaleFactor: richText.textScaleFactor,
        maxLines: this.maxLines,
        locale: richText.locale);
    }

    return children.first;
  }

  T _findWidgetOfType<T>(Widget widget) {
    if (widget is T) {
      return widget as T;
    }

    if (widget is MultiChildRenderObjectWidget) {
      MultiChildRenderObjectWidget multiChild = widget;
      for (var child in multiChild.children) {
        return _findWidgetOfType<T>(child);
      }
    } else if (widget is SingleChildRenderObjectWidget) {
      SingleChildRenderObjectWidget singleChild = widget;
      return _findWidgetOfType<T>(singleChild.child);
    }

    return null;
  }
}

推荐阅读