flutter_html
| 截图 1 | 截图 2 | 截图 3 |
![]() |
![]() |
![]() |
安装
将以下内容添加到您的 pubspec.yaml 文件中
dependencies:
flutter_html: ^1.3.0
当前支持的 HTML 标签
a |
abbr |
acronym |
address |
article |
aside |
audio |
b |
bdi |
bdo |
big |
blockquote |
body |
br |
caption |
cite |
code |
data |
dd |
del |
details |
dfn |
div |
dl |
dt |
em |
figcaption |
figure |
footer |
h1 |
h2 |
h3 |
h4 |
h5 |
h6 |
header |
hr |
i |
iframe |
img |
ins |
kbd |
li |
main |
mark |
nav |
noscript |
ol |
p |
pre |
q |
rp |
rt |
ruby |
s |
samp |
section |
small |
span |
strike |
strong |
sub |
sup |
summary |
svg |
table |
tbody |
td |
template |
tfoot |
th |
thead |
time |
tr |
tt |
u |
ul |
var |
video |
math: |
mrow |
msup |
msub |
mover |
munder |
msubsup |
moverunder |
mfrac |
mlongdiv |
msqrt |
mroot |
mi |
mn |
mo |
当前支持的 CSS 属性
background-color |
color |
direction |
display |
font-family |
font-feature-settings |
font-size |
font-style |
font-weight |
高度 |
letter-spacing |
line-height |
list-style-type |
list-style-position |
padding |
margin |
text-align |
text-decoration |
text-decoration-color |
text-decoration-style |
text-decoration-thickness |
text-shadow |
vertical-align |
white-space |
width |
word-spacing |
当前支持的内联 CSS 属性
background-color |
border |
color |
direction |
display |
font-family |
font-feature-settings |
font-size |
font-style |
font-weight |
line-height |
list-style-type |
list-style-position |
padding |
margin |
text-align |
text-decoration |
text-decoration-color |
text-decoration-style |
text-shadow |
找不到您需要的标签或属性?提交功能请求或为项目做出贡献!
为什么选择此软件包?
此软件包的设计宗旨是简洁。最初是为了允许将基本的 HTML 内容渲染到 Flutter 小部件树中而创建的,
该项目已扩展到支持基本的样式!
如果您需要更强大、更可自定义的功能,该软件包还提供了许多可选的自定义 API,可用于对小部件渲染进行极其精细化的控制!
API 参考
有关完整的 API 参考,请参见 此处。
有关完整的示例,请参见 此处。
下面,您将找到 `Html` 小部件接受的参数的简要说明以及一些代码片段,以帮助您使用此软件包。
构造函数
该软件包目前有两个不同的构造函数 – `Html()` 和 `Html.fromDom()`。
`Html()` 构造函数适用于那些希望直接将 HTML 从源传递给软件包进行渲染的人。
如果您想在渲染 HTML 之前对其进行修改或清理,那么 `Html.fromDom()` 是您的理想选择 – 您可以将 HTML 字符串转换为 `Document` 并使用其方法按需修改 HTML。然后,您可以直接将修改后的 `Document` 传递给软件包。这样就无需将修改后的 `Document` 解析回字符串,传递给 `Html()`,然后转换回 `Document`,从而缩短了加载时间。
参数
| 参数 | 描述 |
|---|---|
data |
传递给 `Html` 小部件的 HTML 数据。在使用 `Html()` 时,此项是必需的,并且不能为空。 |
document |
传递给 `Html` 小部件的 DOM 文档。在使用 `Html.fromDom()` 时,此项是必需的,并且不能为空。 |
onLinkTap |
一个函数,用于定义小部件在链接被点击时应执行的操作。该函数会将链接的 `src` 作为 `String` 暴露出来供您在实现中使用。 |
customRender |
一个强大的 API,允许您自定义渲染特定 HTML 标签时的所有内容。 |
onImageError |
一个函数,用于定义小部件在图片加载失败时应执行的操作。该函数会将异常 `Object` 和 `StackTrace` 暴露出来供您在实现中使用。 |
omMathError |
一个函数,用于定义小部件在数学公式渲染失败时应执行的操作。该函数会将解析后的 Tex `String`,以及 `flutter_math` 的错误和带类型的错误作为 `String` 暴露出来。 |
shrinkWrap |
一个 `bool` 值,在渲染不同小部件时使用,用于指定它们是否应被收缩包装,例如 `ContainerSpan` |
onImageTap |
一个函数,用于定义小部件在图片被点击时应执行的操作。该函数会将图片的 `src` 作为 `String` 暴露出来供您在实现中使用。 |
blacklistedElements |
一个列表,其中包含 `Html` 小部件不应渲染的元素。列表应包含您希望列入黑名单的 HTML 元素的标签。 |
style |
一个强大的 API,允许您自定义渲染特定 HTML 标签时应使用的样式。 |
navigationDelegateForIframe |
允许您为 `Html` 小部件渲染的所有 iframe 的 `WebView` 设置 `NavigationDelegate`。 |
customImageRender |
一个强大的 API,允许您完全自定义图片的加载方式。 |
数据
作为 `String` 传递给 `Html` 小部件的 HTML 数据。在使用 `Html` 时,此项是必需的,并且不能为空。
字符串中任何不支持该软件包的 HTML 标签都不会被渲染。
示例用法 – 数据
Widget html = Html(
data: """<div>
<h1>Demo Page</h1>
<p>This is a fantastic product that you should buy!</p>
<h3>Features</h3>
<ul>
<li>It actually works</li>
<li>It exists</li>
<li>It doesn't cost much!</li>
</ul>
<!--You can pretty much put any html in here!-->
</div>""",
);
文档
作为 `Document` 传递给 `Html` 小部件的 DOM 文档。在使用 `Html.fromDom()` 时,此项是必需的,并且不能为空。
文档中任何不支持该软件包的 HTML 标签都不会被渲染。
使用 `Html.fromDom()` 构造函数在将 HTML 字符串传递给软件包之前对其进行清理可能很有用。
示例用法 – 文档
import 'package:html/parser.dart' as htmlparser;
import 'package:html/dom.dart' as dom;
...
String htmlData = """<div>
<h1>Demo Page</h1>
<p>This is a fantastic product that you should buy!</p>
<h3>Features</h3>
<ul>
<li>It actually works</li>
<li>It exists</li>
<li>It doesn't cost much!</li>
</ul>
<!--You can pretty much put any html in here!-->
</div>""";
dom.Document document = htmlparser.parse(htmlData);
/// sanitize or query document here
Widget html = Html(
document: document,
);
onLinkTap
一个函数,用于定义小部件在链接被点击时应执行的操作。
示例用法 – onLinkTap
Widget html = Html(
data: """<p>
Linking to <a href='https://github.com'>websites</a> has never been easier.
</p>""",
onLinkTap: (String? url, RenderContext context, Map<String, String> attributes, dom.Element? element) {
//open URL in webview, or launch URL in browser, or any other logic here
}
);
customRender
一个强大的 API,允许您自定义渲染特定 HTML 标签时的所有内容。这意味着您可以为不受本机支持的 HTML 元素添加支持。您还可以在 HTML 中创建自己的自定义标签!
`customRender` 接受一个 `Map
要使用此 API,请将键设置为您要提供自定义实现的 HTML 元素的标签,并创建一个具有上述参数并返回 `Widget` 的函数。
示例用法 – customRender
- 简单示例 – 渲染自定义 HTML 标签
查看代码
Widget html = Html(
data: """
<h3>Display bird element and flutter element <bird></bird></h3>
<flutter></flutter>
<flutter horizontal></flutter>
""",
customRender: {
"bird": (RenderContext context, Widget child, Map<String, String> attributes, dom.Element? element) {
return TextSpan(text: "?");
},
"flutter": (RenderContext context, Widget child, Map<String, String> attributes, dom.Element? element) {
return FlutterLogo(
style: (attributes['horizontal'] != null)
? FlutterLogoStyle.horizontal
: FlutterLogoStyle.markOnly,
textColor: context.style.color,
size: context.style.fontSize.size * 5,
);
},
},
);
- 复杂示例 – 根据嵌入的是 YouTube 视频还是其他嵌入式内容,以不同的方式渲染 `iframe`
查看代码
Widget html = Html(
data: """
<h3>Google iframe:</h3>
<iframe src="https://google.com"></iframe>
<h3>YouTube iframe:</h3>
<iframe src="https://www.youtube.com/embed/tgbNymZ7vqY"></iframe>
""",
customRender: {
"iframe": (RenderContext context, Widget child, Map<String, String> attributes, dom.Element? element) {
if (attributes != null) {
double width = double.tryParse(attributes['width'] ?? "");
double height = double.tryParse(attributes['height'] ?? "");
return Container(
width: width ?? (height ?? 150) * 2,
height: height ?? (width ?? 300) / 2,
child: WebView(
initialUrl: attributes['src'] ?? "about:blank",
javascriptMode: JavascriptMode.unrestricted,
//no need for scrolling gesture recognizers on embedded youtube, so set gestureRecognizers null
//on other iframe content scrolling might be necessary, so use VerticalDragGestureRecognizer
gestureRecognizers: attributes['src'] != null && attributes['src']!.contains("youtube.com/embed") ? null : [
Factory(() => VerticalDragGestureRecognizer())
].toSet(),
navigationDelegate: (NavigationRequest request) async {
//no need to load any url besides the embedded youtube url when displaying embedded youtube, so prevent url loading
//on other iframe content allow all url loading
if (attributes['src'] != null && attributes['src']!.contains("youtube.com/embed")) {
if (!request.url.contains("youtube.com/embed")) {
return NavigationDecision.prevent;
} else {
return NavigationDecision.navigate;
}
} else {
return NavigationDecision.navigate;
}
},
),
);
} else {
return Container(height: 0);
}
}
}
);
更多示例用法和详细信息可在此处找到:此处。
onImageError
一个函数,用于定义小部件在图片加载失败时应执行的操作。该函数会将异常 `Object` 和 `StackTrace` 暴露出来供您在实现中使用。
示例用法 – onImageError
Widget html = Html(
data: """<img alt='Alt Text of an intentionally broken image' src='https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30d'/>""",
onImageError: (Exception exception, StackTrace stackTrace) {
FirebaseCrashlytics.instance.recordError(exception, stackTrace);
},
);
onMathError
一个函数,用于定义小部件在数学公式渲染失败时应执行的操作。该函数会将解析后的 Tex `String`,以及 `flutter_math` 的错误和带类型的错误作为 `String` 暴露出来。
示例用法 – onMathError
Widget html = Html(
data: """<!-- Some MathML string that fails to parse -->""",
onMathError: (String parsedTex, String error, String errorWithType) {
//your logic here. A Widget must be returned from this function:
return Text(error);
//you can also try and fix the parsing yourself:
return Math.tex(correctedParsedTex);
},
);
onImageTap
一个函数,用于定义小部件在图片被点击时应执行的操作。
示例用法 – onImageTap
Widget html = Html(
data: """<img alt='Google' src='https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png' />""",
onImageTap: (String? url, RenderContext context, Map<String, String> attributes, dom.Element? element) {
//open image in webview, or launch image in browser, or any other logic here
}
);
blacklistedElements
一个列表,其中包含 `Html` 小部件不应渲染的元素。列表应包含您希望列入黑名单的 HTML 元素的标签。
示例用法 – blacklistedElements
您可能会遇到两种不同的 HTML 标签用于显示相同内容的情况。在下面的示例中,`<video>` 和 `<iframe>` 元素将显示相同的内容。
`blacklistedElements` 参数允许您更改要渲染的元素。iframe 可能很有优势,因为它们支持并行加载 – Flutter 只需等待 webview 初始化即可渲染页面,可能会缩短加载时间。视频可能很有优势,因为它提供了与 Flutter 小部件 100% 原生的体验,但渲染页面可能需要更多时间。您可能知道 Flutter webview 在 Android 上目前的运行状态有点卡顿,因此使用 `blacklistedElements` 和一个简单的条件,您可以获得两全其美——为 Android 选择视频小部件进行渲染,为 iOS 选择 iframe webview 进行渲染。
Widget html = Html(
data: """
<video controls>
<source src="https://w3schools.org.cn/html/mov_bbb.mp4" />
</video>
<iframe src="https://w3schools.org.cn/html/mov_bbb.mp4"></iframe>""",
blacklistedElements: [Platform.isAndroid ? "iframe" : "video"]
);
style
一个强大的 API,允许您自定义渲染特定 HTML 标签时应使用的样式。
`style` 接受一个 `Map
要使用此 API,请将键设置为您希望提供自定义实现的 HTML 元素的标签,并将值设置为包含您的自定义项的 `Style`。
示例用法 – style
Widget html = Html(
data: """
<h1>Table support:</h1>
<table>
<colgroup>
<col width="50%" />
<col span="2" width="25%" />
</colgroup>
<thead>
<tr><th>One</th><th>Two</th><th>Three</th></tr>
</thead>
<tbody>
<tr>
<td rowspan='2'>Rowspan\nRowspan\nRowspan\nRowspan\nRowspan\nRowspan\nRowspan\nRowspan\nRowspan\nRowspan</td><td>Data</td><td>Data</td>
</tr>
<tr>
<td colspan="2"><img alt='Google' src='https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png' /></td>
</tr>
</tbody>
<tfoot>
<tr><td>fData</td><td>fData</td><td>fData</td></tr>
</tfoot>
</table>""",
style: {
// tables will have the below background color
"table": Style(
backgroundColor: Color.fromARGB(0x50, 0xee, 0xee, 0xee),
),
// some other granular customizations are also possible
"tr": Style(
border: Border(bottom: BorderSide(color: Colors.grey)),
),
"th": Style(
padding: EdgeInsets.all(6),
backgroundColor: Colors.grey,
),
"td": Style(
padding: EdgeInsets.all(6),
alignment: Alignment.topLeft,
),
// text that renders h1 elements will be red
"h1": Style(color: Colors.red),
}
);
更多示例和详细信息可在此处找到:此处。
navigationDelegateForIframe
允许您为 `Html` 小部件渲染的所有 iframe 的 `WebView` 设置 `NavigationDelegate`。您可以使用 `NavigationDelegate` 来阻止或允许加载特定 URL。
示例用法 – navigationDelegateForIframe
Widget html = Html(
data: """
<h3>YouTube iframe:</h3>
<iframe src="https://google.com"></iframe>
<h3>Google iframe:</h3>
<iframe src="https://www.youtube.com/embed/tgbNymZ7vqY"></iframe>
""",
navigationDelegateForIframe: (NavigationRequest request) {
if (request.url.contains("google.com/images")) {
return NavigationDecision.prevent;
} else {
return NavigationDecision.navigate;
}
},
);
customImageRender
一个强大的 API,允许您自定义 `Html` 小部件在渲染图片时的行为,直至最细微的细节。
`customImageRender` 接受一个 `Map
默认的图片渲染是
final Map<ImageSourceMatcher, ImageRender> defaultImageRenders = {
base64UriMatcher(): base64ImageRender(),
assetUriMatcher(): assetImageRender(),
networkSourceMatcher(extension: "svg"): svgNetworkImageRender(),
networkSourceMatcher(): networkImageRender(),
};
有关这些实现方式的详细信息,请参见 源代码。
当设置 `customImageRenders` 时,该软件包将优先使用自定义渲染,而默认渲染作为回退。
注意:在设置 `customImageRenders` 时,顺序非常重要。您的 `ImageSourceMatcher` 越具体,它在 `customImageRender` 列表中的位置就应该越高。
typedef ImageSourceMatcher
这是一个类型,定义为传递属性(作为 `Map
典型的用法如下所示
ImageSourceMatcher base64UriMatcher() => (attributes, element) =>
attributes["src"] != null &&
attributes["src"]!.startsWith("data:image") &&
attributes["src"]!.contains("base64,");
在上面的示例中,匹配器检查图片的 `src` 是否以“data:image”开头或包含“base64,” (这表明图像数据确实是 base64),因为这些都表示 base64 格式的图像。
您也可以在函数本身中声明自己的变量,如下所示
ImageSourceMatcher networkSourceMatcher({
/// all three are optional, you don't need to have these in the function
List<String> schemas: const ["https", "http"],
List<String> domains: const ["your domain 1", "your domain 2"],
String extension: "your extension",
}) =>
(attributes, element) {
final src = Uri.parse(attributes["src"] ?? "about:blank");
return schemas.contains(src.scheme) &&
domains.contains(src.host) &&
src.path.endsWith(".$extension");
};
在上面的示例中,将可能的 schema 与 `src` 的 schema 进行比较,还可以选择性地检查域和扩展名。此实现允许对匹配的图片进行极其精细化的控制,甚至可以通过变量即时更改。
typedef ImageRender
这是一个类型,定义为传递图片属性(作为 `Map
典型的用法可能如下所示
ImageRender base64ImageRender() => (context, attributes, element) {
final decodedImage = base64.decode(attributes["src"] != null ?
attributes["src"].split("base64,")[1].trim() : "about:blank");
return Image.memory(
decodedImage,
);
};
上面的示例应与 `ImageSourceMatcher` 示例中的 `base64UriMatcher()` 一起使用。
与 `ImageSourceMatcher` 的函数一样,您也可以在函数本身中声明自己的变量
ImageRender networkImageRender({
Map<String, String> headers,
double width,
double height,
Widget Function(String) altWidget,
}) =>
(context, attributes, element) {
return Image.network(
attributes["src"] ?? "about:blank",
headers: headers,
width: width,
height: height,
frameBuilder: (ctx, child, frame, _) {
if (frame == null) {
return altWidget.call(attributes["alt"]) ??
Text(attributes["alt"] ?? "",
style: context.style.generateTextStyle());
}
return child;
},
);
};
实现这些变量可以让你自定义小部件渲染的每一个细节。
示例用法 – customImageRender
`customImageRender` 可以通过两种不同的方式使用
- 覆盖默认渲染
Widget html = Html(
data: """
<img alt='Flutter' src='https://flutterdart.cn/assets/flutter-lockup-1caf6476beed76adec3c477586da54de6b552b2f42108ec5bc68dc63bae2df75.png' /><br />
<img alt='Google' src='https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png' /><br />
""",
customImageRenders: {
networkSourceMatcher(domains: ["flutter.dev"]):
(context, attributes, element) {
return FlutterLogo(size: 36);
},
networkSourceMatcher(): networkImageRender(
headers: {"Custom-Header": "some-value"},
altWidget: (alt) => Text(alt ?? ""),
loadingWidget: () => Text("Loading..."),
),
(attr, _) => attr["src"] != null && attr["src"]!.startsWith("/wiki"):
networkImageRender(
mapUrl: (url) => "https://upload.wikimedia.org" + url),
},
);
上面有三个自定义的 `networkSourceMatcher`,它们将按顺序应用,然后是默认实现。
当检测到 URL 为 `flutter.dev` 的图片时,渲染器将显示 flutter logo,而不是显示图片。如果图片是其他任何图片,它会保留默认的小部件,但会设置 headers 和 alt 文本以防图片损坏。最后一个渲染器处理相对路径,方法是重写它们,具体来说是加上一个基础 URL 前缀。请注意,前面的自定义渲染器的自定义设置不适用。例如,第二个渲染器应用的 headers 在第三个渲染器中不适用。
- 创建自己的渲染器
ImageSourceMatcher classAndIdMatcher({String classToMatch, String idToMatch}) => (attributes, element) =>
attributes["class"] != null && attributes["id"] != null &&
(attributes["class"]!.contains(classToMatch) ||
attributes["id"]!.contains(idToMatch));
ImageRender classAndIdRender({String classToMatch, String idToMatch}) => (context, attributes, element) {
if (attributes["class"] != null && attributes["class"]!.contains(classToMatch)) {
return Image.asset(attributes["src"] ?? "about:blank");
} else {
return Image.network(
attributes["src"] ?? "about:blank",
semanticLabel: attributes["longdesc"] ?? "",
width: attributes["width"],
height: attributes["height"],
color: context.style.color,
frameBuilder: (ctx, child, frame, _) {
if (frame == null) {
return Text(attributes["alt"] ?? "", style: context.style.generateTextStyle());
}
return child;
},
);
}
};
Widget html = Html(
data: """
<img alt='alt text' class='class1-class2' src='assets/flutter.png' /><br />
<img alt='alt text 2' id='imageId' src='https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png' /><br />
""",
customImageRenders: {
classAndIdMatcher(classToMatch: "class1", idToMatch: "imageId"): classAndIdRender(classToMatch: "class1", idToMatch: "imageId")
},
);
上面的示例有一个匹配器,用于检查类名或 ID,然后根据是否匹配类名或 ID 返回两个不同的小部件。
使用自定义图片渲染器,天空是极限。您可以根据需要将其设置为非常具体,或者设置为包罗万象,并且您拥有对所有内容的完全控制。此外,您还可以使用软件包的样式解析来处理自定义小部件,使您的代码看起来整洁易读!
渲染参考
本节将介绍此软件包如何渲染某些 HTML 元素,以便您可以评估您的 HTML 将如何渲染并据此进行构建。
图片
该软件包目前支持 base64 图片、资源图片、`<img>` 中的网络 SVG 以及网络图片。
该软件包使用图片的 `src` 来确定渲染上述哪种类型。顺序如下
- 如果 `src` 为 null,则渲染图片(如果存在)的 alt 文本。
- 如果 `src` 以“data:image”开头并包含“base64,” (这表明图片数据确实是 base64),则从 base64 数据渲染 `Image.memory`。
- 如果 `src` 以“asset:”开头,则从 `src` 中的路径渲染 `Image.asset`。
- 如果 `src` 以“.svg”结尾,则渲染 `SvgPicture.network`(来自 `flutter_svg` 软件包)
- 否则,只渲染 `Image.network`。
如果上述任何一种渲染失败,软件包将回退到渲染图片的 alt 文本(如果存在)。
目前,该软件包在渲染图片时仅考虑 width、height、src 和 alt 文本。
请注意,目前不支持 base64 格式或资源格式的 SVG。
Iframe
该软件包使用 `webview_flutter` 插件来渲染 iframe。
渲染 iframe 时,该软件包会考虑 width、height 和 sandbox 属性。
Sandbox 控制 webview 的 JavaScript 模式 – 值为 `null` 或 `allow-scripts` 将设置 `javascriptMode: JavascriptMode.unrestricted`,否则将设置 `javascriptMode: JavascriptMode.disabled`。
您可以使用 `navigationDelegateForIframe` 属性设置 webview 的 `navigationDelegate` – 有关更多详细信息,请参见 此处。
音频
该软件包使用 `chewie_audio` 插件来渲染音频元素。
渲染音频小部件时,该软件包会考虑 `controls`、`loop`、`src`、`autoplay`、`width` 和 `muted` 等属性。
视频
该软件包使用 `chewie` 插件来渲染视频元素。
渲染视频小部件时,该软件包会考虑 `controls`、`loop`、`src`、`autoplay`、`poster`、`width`、`height` 和 `muted` 等属性。
SVG
该软件包使用 `flutter_svg` 插件来渲染 SVG 元素。
渲染 SVG 时,该软件包会获取 `<svg>` 标签中的 SVG 数据并将其传递给 `flutter_svg`。渲染时会考虑 `width` 和 `height` 属性(如果提供)。
MathML
该软件包使用 `flutter_math` 插件来渲染 MathML 元素。
渲染 MathML 时,该软件包会获取 `<math>` 标签中的 MathML 数据并尝试将其解析为 Tex。然后,它会将解析后的字符串传递给 `flutter_math`。
由于该软件包将 MathML 解析为 Tex,因此它可能不支持某些功能。当前支持的标签列表可以在 上面 找到,但其中一些目前仅提供部分支持。
如果解析出错,您可以使用 `onMathError` API 来捕获错误并可能在您端进行修复 – 您可以分析错误和解析后的字符串,最后返回一个带有已更正 Tex 字符串的 `Math.tex()` 新实例。
如果您想看到更多 MathML 功能,欢迎创建 PR 或提交功能请求!
Tex
如果您有一个想要在 HTML 中渲染的 Tex 字符串,您可以使用相同的 `flutter_math` 插件来实现。
在 HTML 中使用自定义标签(例如 `<tex>`),并将您的 **原始** Tex 字符串放在其中。
然后,使用 `customRender` 参数添加要渲染 Tex 的小部件。它可能看起来像这样
Widget htmlWidget = Html(
data: r"""<tex>i\hbar\frac{\partial}{\partial t}\Psi(\vec x,t) = -\frac{\hbar}{2m}\nabla^2\Psi(\vec x,t)+ V(\vec x)\Psi(\vec x,t)</tex>""",
customRender: {
"tex": (_, __, ___, element) => Math.tex(
element.text,
onErrorFallback: (FlutterMathException e) {
//return your error widget here e.g.
return Text(e.message);
},
),
}
);
表格
该软件包使用 `flutter_layout_grid` 插件来渲染表格元素。
渲染表格元素时,该软件包会尝试计算每个元素的最佳匹配并相应地调整其单元格大小。在此过程中会考虑 `Rowspan` 和 `colspan`,因此跨越多行和多列的单元格会按预期渲染。高度是根据内容确定的,以保持单元格的最佳宽高比。
注意事项
- 如果您想在 `Row()` 中使用此小部件,请确保设置 `shrinkWrap: true` 并将您的组件放在 `expanded` 中
Widget row = Row(
children: [
Expanded(
child: Html(
shrinkWrap: true,
//other params
)
),
//whatever other widgets
]
);
迁移指南
- 对于 1.0 版本 – 指南
贡献指南
即将推出!
同时,欢迎随时提交 PR


