flutter - 强制容器内的小部件将自身限制为一行
问题描述
我对 Flutter 比较陌生,并且有一个我觉得应该很容易解决的布局问题。我正在尝试将 a MarkdownBody
(包含一些 HTML 文本)呈现为 a 的标题ListTile
。如果标题太长,就会溢出。如果我可以使用Text
小部件而不是 aMarkdownBody
那么解决方案将非常简单:使用maxLines: 1
和overflow: 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
, Row
with Expanded
, 但无法解决溢出问题。
我怎样才能做到这一点?
解决方案
理想的解决方案是克隆原始包并在其中添加一个额外的小部件,以便您可以在和/或设置为限制生成的子项时提供overflow
/maxLines
属性并中断/扩展解析逻辑。overflow
maxLines
假设降价的长度对于您的传入数据来说是最小的,您可以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;
}
}
推荐阅读
- javascript - 与 await Delay() 的数学不一致
- python - 比较 pandas 中以 kbs、mbs 和 gbs 为单位的列中值的大小
- flutter - 如何多次写入我的 JSON 文件?当点击按下?
- c# - 如何将出生日期添加到 DateTime c#
- android - NewGlobalRef 在不同的.so 上调用了挂起的异常 java.lang.ClassNotFoundException
- python - pyenv-win 术语“youtube-dl”未被识别为 cmdlet、函数、脚本文件或可运行程序的名称
- android - Toast 消息一直显示在屏幕底部
- django - 如何将 Apache Guacamole 与 Django 一起用于 Web 应用程序?(不使用默认客户端)
- lua - 表同时为 nil 和非 nil
- http - 如何使用来自 about:blank 的 Discord 机器人发送消息?