Flutter webview_flutter 4.x JS交互与高度自适应实战

小石头
小石头
发布时间:2026-10-15| 5人浏览过
原创

详解 Flutter webview_flutter 4.x 版本的 JavaScript 双向交互、动态高度自适应以及 URL 拦截技巧,解决新版 API 变更带来的重构问题。

版本差异与核心变化

在开始编写代码前,需明确 webview_flutter 4.x 相比旧版本(3.x)的关键变化,避免使用过时的 API:

  • 组件拆分:原有的 WebView 类被移除,拆分为 WebViewController(控制器/逻辑处理)和 WebViewWidget(UI 渲染)。这种分离允许提前初始化 Controller。
  • Android 适配简化:不再需要手动判断 Android 系统版本来选择 Hybrid Composition 还是 Texture Layer。插件内部已自动处理底层实现(Android 19+ 使用混合模式,23+ 使用纹理层)。

本文基于当前稳定版本 4.0.x 进行讲解,涵盖从环境准备到高级 JS 交互的完整流程。

环境准备

1. 配置最低 SDK 版本

虽然文档支持 Android SDK 19+,但为了保证插件兼容性及使用最新的 Android 特性(如 Texture Layer Hybrid Composition),建议将 minSdkVersion 设置为 21 或更高。

// android/app/build.gradle
android {
    defaultConfig {
        minSdkVersion 21
    }
}

iOS 默认支持 11.0 及以上,无需额外调整。

2. 安装依赖

在项目根目录执行以下命令添加插件:

flutter pub add webview_flutter

基础示例与启用 JS

新建一个 Stateful Widget 来承载 WebView。关键在于初始化时启用非受限的 JavaScript 模式,否则大部分现代网页将无法运行。

class _MyWebViewState extends State<MyWebView> {
  late final WebViewController controller;
  double height = 0;

  @override
  void initState() {
    super.initState();
    // 1. 创建 Controller 并配置
    controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted) // 必须开启 JS
      ..loadHtmlString('''
        <!DOCTYPE html>
        <html><body><h1>Hello World</h1></body></html>
      ''');
  }

  @override
  Widget build(BuildContext context) {
    return WebViewWidget(controller: controller);
  }
}

WebView 高度自适应方案

WebViewWidget 会尝试占据最大可用空间。若未设置容器限制,会导致布局溢出;若使用固定高度的 SizedBox,内容过多时会遮挡或出现大片空白。理想的方案是根据页面实际内容高度动态调整。

方案一:网页主动报告高度

如果 H5 页面是团队内部可控的,最稳定的方式是让 JS 通过 postMessage 通知 Dart 侧页面高度。

H5 端 (HTML/JS):

<script>
const resizeObserver = new ResizeObserver(entries => {
    Report.postMessage(document.scrollingElement.scrollHeight)
});
resizeObserver.observe(document.body);
</script>

Dart 端:

定义与 H5 中一致的 Channel 名称 Report,接收消息后更新状态。

controller.addJavaScriptChannel('Report', onMessageReceived: (message) {
  setState(() {
    height = double.parse(message.message);
  });
});

方案二:无法修改源码时的注入方案

对于外部链接或第三方 H5,无法修改其源码时,需由 Flutter 侧注入 JS 脚本监听页面变化。

核心逻辑:

  1. 等待页面加载完成 (onPageFinished)。
  2. 注入包含 ResizeObserver 的脚本。
  3. 脚本将高度值发送给 Flutter 定义的 Channel。
controller.setNavigationDelegate(NavigationDelegate(
  onPageFinished: (url) async {
    // 页面加载完成后注入监听脚本
    await controller.runJavaScript('''
      const resizeObserver = new ResizeObserver(entries => 
        Report.postMessage(document.scrollingElement.scrollHeight));
      resizeObserver.observe(document.body);
    ''');
  },
));

注意点:

  • 必须在页面加载完成后注入,否则 DOM 尚未就绪,脚本无效。
  • 可结合 Timer 对频繁触发的消息进行节流,防止 UI 频繁重绘。
  • 设置最大高度限制,防止无限增长导致内存或布局错误。

Dart 与 JS 双向交互

1. Dart 接收 JS 调用 (JavaScriptChannel)

定义一个名为 Jump 的通道,JS 端调用 Jump.postMessage('target') 即可触发 Flutter 回调。

controller.addJavaScriptChannel('Jump', onMessageReceived: (msg) {
  if (msg.message == 'video') {
    // 执行 Flutter 端的业务逻辑,如打开相机或播放视频
    openVideoPlayer();
  }
});

2. JS 调用 Dart 代码获取数据

Dart 可通过 runJavaScriptReturningResult 执行 JS 并返回值。

var result = await controller.runJavaScriptReturningResult('document.title');

3. 拦截 URL 跳转至原生页面

通过在 NavDelegate 中拦截特定 Scheme 的 URL,实现 H5 点击后打开 App 内原生页面。

controller.setNavigationDelegate(NavigationDelegate(
  onNavigationRequest: (request) {
    if (request.url.endsWith('/open-native-page')) {
      return NavigationDecision.prevent; // 阻止 WebView 加载
    }
    return NavigationDecision.navigate;
  },
));

H5 触发方式可以是 <a href="app://native"> 或 JS 修改 window.location.href。

最佳实践与总结

在进行 WebView 开发时,应遵循以下原则以权衡利弊:

  • 控制权归属: 优先让 H5 页面自身处理布局和样式控制,Flutter 侧仅做必要的事件桥接。单方面强力注入 CSS/JS 虽灵活,但可能导致 H5 更新后的兼容性断裂。
  • 性能优化: 避免在 JS 中频繁调用 postMessage,建议使用防抖或节流策略发送高度等高频状态。
  • 加载方式: 示例中为了直观使用了 loadHtmlString,生产环境中建议使用 loadRequest(Uri.parse(url)) 加载远程网址。

以上就是 js 交互在 Flutter 中使用 webview_flutter 的详细内容,更多关于 Flutter WebView 性能优化与跨端通信的资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。