Flutter安全解析HTML插件flutter_html_null_safe的使用

Flutter安全解析HTML插件flutter_html_null_safe的使用

flutter_html介绍

flutter_html 是一个用于在Flutter应用程序中渲染HTML和CSS内容的插件。它提供了丰富的功能来处理各种HTML标签和CSS属性。

Widget build(context) {
  return Html(
    data: """
        <h1>Hello, World!</h1>
        <p><span style="font-style:italic;">flutter_html</span> supports a variety of HTML and CSS tags and attributes.</p>
        <p>Over a hundred static tags are supported out of the box.</p>
        <p>Or you can even define your own using an <code>Extension</code>: <flutter></flutter></p>
        <p>Its easy to add custom styles to your Html as well using the <code>Style</code> class:</p>
        <p class="fancy">Here's a fancy <p> element!</p>
        """,
    extensions: [
      TagExtension(
        tagsToExtend: {"flutter"},
        child: const FlutterLogo(),
      ),
    ],
    style: {
      "p.fancy": Style(
        textAlign: TextAlign.center,
        padding: const EdgeInsets.all(16),
        backgroundColor: Colors.grey,
        margin: Margins(left: Margin(50, Unit.px), right: Margin.auto()),
        width: Width(300, Unit.px),
        fontWeight: FontWeight.bold,
      ),
    },
  );
}

上述代码将生成以下效果:

渲染效果

目录

为什么选择flutter_html?

该插件旨在简化HTML内容到Flutter widget树的基本渲染过程。它不仅支持基本样式,还提供了一系列扩展API,以实现对widget渲染的极细粒度控制。

迁移指南

3.0.0迁移指南

API参考

要查看完整的API参考,请访问 这里

构造函数

该插件目前有两个不同的构造函数 - Html()Html.fromDom()

  • Html() 构造函数适用于那些希望直接从源传递HTML给插件进行渲染的用户。
  • 如果你需要在渲染之前修改或清理HTML,那么应该使用 Html.fromDom()。你可以将HTML字符串转换为 Document,然后使用其方法来修改HTML,最后将修改后的 Document 直接传递给插件。这避免了重新解析修改后的 Document 并将其转换回字符串再传递给 Html() 的步骤,从而减少了加载时间。

参数表

参数 描述
data 传递给 Html widget的HTML数据。当使用 Html() 时,这是必需且不能为null的。
document 传递给 Html widget的DOM文档。当使用 Html.fromDom() 时,这是必需且不能为null的。
onLinkTap 可选。定义当点击链接时widget应执行的操作。该函数暴露了链接的 src 作为 String 供你使用。
extensions 可选。一个强大的API,允许你在渲染特定HTML标签时自定义一切。
shrinkWrap 可选。一个 bool,在渲染不同小部件时指定它们是否应该被包裹起来,例如 ContainerSpan
onlyRenderTheseTags 可选。一个唯一的元素集合,Html widget 应该渲染。注意,如果您的HTML没有包含 <body><html>,则这些标签将自动添加,因此你应该包括这些标签。
doNotRenderTheseTags 可选。一组不应由 Html widget 渲染的标签。
style 可选。一个强大的API,允许你自定义渲染特定HTML标签时使用的样式。

更多示例和详细信息,请参阅:

外部包

flutter_html_all

这是一个方便的包,导出了所有其他外部包。如果你打算渲染所有需要外部依赖的标签,应该使用这个包。

flutter_html_audio

该包使用 chewie_audiovideo_player 插件渲染音频元素。

该包考虑了以下属性:controlsloopsrcautoplaywidthmuted

添加AudioHtmlExtension

pubspec.yaml 中添加依赖:

flutter pub add flutter_html_audio

然后在你的代码中导入并使用:

import 'package:flutter_html_audio/flutter_html_audio';

Widget html = Html(
  data: myHtml,
  extensions: [
    AudioHtmlExtension(),
  ],
);

flutter_html_iframe

该包使用 webview_flutter 插件渲染iframe。

在渲染iframe时,该包考虑了宽度、高度和sandbox属性。

Sandbox 控制webview的JavaScript模式 - nullallow-scripts 将设置 javascriptMode: JavascriptMode.unrestricted,否则将设置 javascriptMode: JavascriptMode.disabled

添加IframeHtmlExtension

pubspec.yaml 中添加依赖:

flutter pub add flutter_html_iframe

然后在你的代码中导入并使用:

import 'package:flutter_html_iframe/flutter_html_iframe';

Widget html = Html(
  data: myHtml,
  extensions: [
    IframeHtmlExtension(),
  ],
);

你可以通过 IframeHtmlExtensionnavigationDelegate 属性设置webview的 navigationDelegate。这允许你阻止或允许某些URL的加载。

flutter_html_math

该包使用 flutter_math_fork 插件渲染MathML元素。

在渲染MathML时,该包会尝试将MathML数据内的 <math> 标签解析为Tex,然后将其传递给 flutter_math_fork

因为该包将MathML解析为Tex,可能不支持一些功能。当前支持的标签列表可以在 Wiki 上找到,但其中一些标签目前只部分支持。

添加MathHtmlExtension

pubspec.yaml 中添加依赖:

flutter pub add flutter_html_math

然后在你的代码中导入并使用:

import 'package:flutter_html_math/flutter_html_math';

Widget html = Html(
  data: myHtml,
  extensions: [
    MathHtmlExtension(),
  ],
);

如果解析出错,你可以使用 MathHtmlExceptiononMathErrorBuilder 属性来捕获错误,并在你的端上尝试修复它。

该函数会暴露解析后的Tex字符串以及来自 flutter_math_fork 的错误和错误类型。

你可以分析错误和解析后的字符串,并最终返回一个新的 Math.tex() 实例,其中包含修正后的Tex字符串。

Tex

如果你想在HTML中渲染Tex字符串,可以使用相同的 flutter_math_fork 插件。

在HTML中使用自定义标签(例如 <tex>),并将原始的Tex字符串放在里面。

然后,使用 extensions 参数添加渲染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>""",
  extensions: [
    TagExtension(
      tagsToExtend: {"tex"},
      builder: (extensionContext) {
        return Math.tex(
          extensionContext.innerHtml,
          mathStyle: MathStyle.display,
          textStyle: extensionContext.styledElement?.style.generateTextStyle(),
          onErrorFallback: (FlutterMathException e) {
            // 你可以在这里尝试纠正Tex字符串
            return Text(e.message);
          },
        );
      }
    ),
  ],
);

flutter_html_svg

该包使用 flutter_svg 插件渲染SVG元素。

在渲染SVG时,该包会将 <svg> 标签内的SVG数据传递给 flutter_svg。如果提供了,则会考虑宽度和高度属性。

该包还提供了几种在 <img> 标签内渲染SVG的方法,特别是base64 SVG、资产SVG和网络SVG。

添加SvgHtmlExtension

pubspec.yaml 中添加依赖:

flutter pub add flutter_html_svg

然后在你的代码中导入并使用:

import 'package:flutter_html_svg/flutter_html_svg';

Widget html = Html(
  data: myHtml,
  extensions: [
    SvgHtmlExtension(),
  ],
);

flutter_html_table

该包使用 flutter_layout_grid 插件渲染表格元素。

在渲染表格元素时,该包会尝试计算每个元素的最佳拟合大小,并相应地调整其单元格大小。考虑到了 <rowspan><colspan>,所以跨越多个行和列的单元格将按预期渲染。高度会根据最佳比例确定,以保持单元格的最佳纵横比。

添加TableHtmlExtension

pubspec.yaml 中添加依赖:

flutter pub add flutter_html_table

然后在你的代码中导入并使用:

import 'package:flutter_html_table/flutter_html_table';

Widget html = Html(
  data: myHtml,
  extensions: [
    TableHtmlExtension(),
  ],
);

flutter_html_video

该包使用 chewievideo_player 插件渲染视频元素。

该包考虑了以下属性:controlsloopsrcautoplayposterwidthheightmuted

添加VideoHtmlExtension

pubspec.yaml 中添加依赖:

flutter pub add flutter_html_video

然后在你的代码中导入并使用:

import 'package:flutter_html_video/flutter_html_video';

Widget html = Html(
  data: myHtml,
  extensions: [
    VideoHtmlExtension(),
  ],
);

常见问题

为什么我看不到 <audio>/<iframe>/<math>/<svg>/<table>?

你是否按照上述说明操作了?

如果是,请随时提出问题或开始讨论以获取额外的帮助。

如何在我的HTML中渲染LaTeX?

请参阅上面的示例。

如何在我的 Row() 中使用此组件?

如果你想在 Row() 中使用此组件,确保设置了 shrinkWrap: true 并将组件放置在 Expanded 中:

Widget row = Row(
   children: [
        Expanded(
            child: Html(
              shrinkWrap: true,
              // 其他参数
            )
        ),
        // 其他组件
   ]
);

更多关于Flutter安全解析HTML插件flutter_html_null_safe的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter安全解析HTML插件flutter_html_null_safe的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


flutter_html_null_safe 是一个用于在 Flutter 应用中安全解析和渲染 HTML 内容的插件。它支持空安全(null safety),并且可以处理常见的 HTML 标签和属性,同时提供了自定义渲染器和处理器的能力,以便开发者可以根据需要定制 HTML 的渲染效果。

安装

首先,你需要在 pubspec.yaml 文件中添加 flutter_html_null_safe 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_html_null_safe: ^2.0.0 # 请根据最新版本号进行替换

然后运行 flutter pub get 来安装依赖。

基本用法

以下是一个简单的示例,展示了如何使用 flutter_html_null_safe 插件来解析和渲染 HTML 内容:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter HTML Example'),
        ),
        body: Html(
          data: """
            <h1>Hello, Flutter!</h1>
            <p>This is an example of <strong>HTML</strong> rendering in Flutter.</p>
            <a href="https://flutter.dev">Visit Flutter</a>
          """,
        ),
      ),
    );
  }
}

自定义样式

你可以通过 style 参数来自定义 HTML 元素的样式。例如,设置所有 <h1> 标签的字体大小和颜色:

Html(
  data: """
    <h1>Hello, Flutter!</h1>
    <p>This is an example of <strong>HTML</strong> rendering in Flutter.</p>
  """,
  style: {
    "h1": Style(
      fontSize: FontSize(24),
      color: Colors.blue,
    ),
    "p": Style(
      fontSize: FontSize(16),
      color: Colors.black,
    ),
  },
)

处理链接

你可以通过 onLinkTap 回调来处理链接的点击事件:

Html(
  data: """
    <a href="https://flutter.dev">Visit Flutter</a>
  """,
  onLinkTap: (url, _, __, ___) {
    print("Link tapped: $url");
    // 在这里处理链接点击事件,例如打开浏览器
  },
)

自定义渲染器

如果你需要自定义某个 HTML 标签的渲染方式,可以使用 customRender 参数。例如,自定义 <img> 标签的渲染:

Html(
  data: """
    <img src="https://via.placeholder.com/150" alt="Placeholder">
  """,
  customRender: {
    "img": (context, child, attributes, _) {
      return Image.network(attributes['src']!);
    },
  },
)
回到顶部