likes
comments
collection
share

Flutter之WebView加载html字符串及高度自适应

作者站长头像
站长
· 阅读数 3

Flutter 官方提供了 webview_flutter 插件用于加载 html 页面,网上有很多使用该插件的 WebView 控件通过 url 加载 html 页面的资料教程,但是加载 html 字符串的资料则相对较少。本篇文章主要讲解如何使用 webview_flutter 插件提供的 WebView 加载 html 字符串。

使用场景

什么时候在开发中会用到使用 WebView 来加载 html 字符串呢?这里举一个笔者在真实项目中遇到的需求,PC 端使用富文本编辑器编辑提交的内容需要在 App 中进行展示,因服务端存储/返回给 App 的就是一段 html 字符串,此时 App 就需要用到 WebView 来对这段 html 字符串内容进行加载显示。

WebView 加载 Html 字符串

添加依赖

在项目的 pubspec.yaml 文件中添加 webview_flutter 插件的依赖:

dependencies:
  webview_flutter: ^3.0.0

加载 html 字符串

导入 webview_flutter 的包:

import 'package:webview_flutter/webview_flutter.dart';

然后使用时直接创建一个 WebView 对象即可。

WebView 构造参数有一个 initialUrl 参数,可以通过该参数传入一个 url 地址加载 html 页面,如下:

Flutter之WebView加载html字符串及高度自适应

但是 WebView 的构造函数中并没有加载 html 字符串的参数,所以无法在创建 WebView 的时候直接加载 html 字符串,需要用到 WebViewController 来进行加载 html 字符串。

WebViewController 提供了 loadHtmlString 或者 loadUrl 方法来加载 html 字符串, WebViewController 需要通过 WebViewonWebViewCreated 回调获取,如下:

WebView(
  javascriptMode: JavascriptMode.unrestricted,
  onWebViewCreated: (WebViewController controller){
    //获取到 WebViewController
  },
)

loadHtmlString

通过 WebViewControllerloadHtmlString 方法加载 html 字符串,参数传入 html 字符串即可,如下:

效果如下:

Flutter之WebView加载html字符串及高度自适应

内容确实加载出来了,但是文字特别小,那是因为在 iOS 上需要在 html 里加上 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 否则默认字体会特别小。修改如下:

效果如下:

Flutter之WebView加载html字符串及高度自适应

除此之外,loadHtmlString 还有一个可选参数 baseUrl ,作用是当 html 字符串中使用到了相对路径的 url 时,设置了 baseUrl 后 WebView 加载 html 请求相应 url 时就会带上 baseUrl,如 html 字符串中有显示图片,图片地址写的是相对路径,此时就可以使用 baseUrl 参数来解决,如下:

效果如下:

Flutter之WebView加载html字符串及高度自适应

loadUrl

除了使用 loadHtmlString 外, 还可以使用 loadUrl 来加载 html 字符串,看到这里可能有些人就会有疑问,loadUrl 不是加载 url 的么怎么也能用来加载 html 字符串? 确实是可以的,但是需要通过 Uri.dataFromString 进行转换。如下:

WebView(
  javascriptMode: JavascriptMode.unrestricted,
  onWebViewCreated: (WebViewController controller){
    controller.loadUrl(Uri.dataFromString(html, mimeType: "text/html", encoding: utf8,).toString());
  },
)

通过 Uri.dataFromString 转换同样可实现加载 html 字符串,需要注意的是 Uri.dataFromString 除了 html 字符串的参数外,还需要设置 mimeType"text/html"encodingutf8 ,如果不设置 encoding 加载时可能会报错,而不设置 mimeType 则会直接把 html 代码加载出来。

WebView 高度自适应

WebView 默认无法做到高度自适应,即根据 html 内容高度自适应,当在 Column 等控件中使用 WebView 而不手动设置固定高度时则会报错。

如果要做到高度自适应,则需要用到 js 方法,在 html 中通过 js 监听页面大小的变化,然后获取页面高度再将高度传递到 Flutter 中,在 Flutter 中获取到高度后再动态改变 WebView 的高度。

实现步骤如下:

  • 给 WebView 添加一个 JavascriptChannel 用于 js 与 Flutter 通信
  • 在 html 中添加 script 使用 ResizeObserver 监听 body 元素的大小变化,在变化回调里调用上一步添加的 JavascriptChannel 发送页面高度的消息
  • 在 Flutter 中接收到消息时,获取 js 发送过来的高度值,然后更新 WebView 的高度

代码如下:

如上,给 WebView 外面包了一层 SizeBox 用于限制 WebView 的高度,同时给 WebView 添加了名为 ResizeJavascriptChannel , 在 html 字符串中添加了 script 使用 js 的 ResizeObserver 监听页面元素大小变化,在变化回调里获取元素的 scrollHeight 值并将其发送到 Flutter,在 Flutter 的 JavascriptChannel 消息回调里获取高度值并更新 SizeBox 的高度。从而实现了 WebView 的高度自适应。

完整代码

转载自:https://juejin.cn/post/7056353175900520462
评论
请登录