精选文章

Flutter WebView 组件

2025-02-11 · 组件

WebView 是高频又敏感的组件,封装的目标是:统一交互、统一安全策略。下面以 flutter_inappwebview 给出可落地范式。

0. 依赖

dependencies:
  flutter_inappwebview: ^6.0.0

1. 统一 WebView 组件

class AppWebView extends StatefulWidget {
  final String url;
  const AppWebView({super.key, required this.url});

  @override
  State<AppWebView> createState() => _AppWebViewState();
}

class _AppWebViewState extends State<AppWebView> {
  InAppWebViewController? _controller;
  bool _loading = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('WebView')),
      body: Stack(
        children: [
          InAppWebView(
            initialUrlRequest: URLRequest(url: WebUri(widget.url)),
            onWebViewCreated: (c) => _controller = c,
            onLoadStart: (_, __) => setState(() => _loading = true),
            onLoadStop: (_, __) => setState(() => _loading = false),
            shouldOverrideUrlLoading: (controller, nav) async {
              final uri = nav.request.url;
              if (uri == null) return NavigationActionPolicy.CANCEL;
              return NavigationActionPolicy.ALLOW;
            },
          ),
          if (_loading) const Center(child: CircularProgressIndicator()),
        ],
      ),
    );
  }
}

2. JS 交互

_controller?.addJavaScriptHandler(
  handlerName: 'bridge',
  callback: (args) {
    // JS -> Flutter
  },
);

_controller?.evaluateJavascript(source: "window.bridgeReady()");

3. 平台配置(关键)

Android:如需加载非 HTTPS,配置 usesCleartextTraffic 与网络安全策略。
iOS:如需加载非 HTTPS,配置 NSAppTransportSecurity

4. 常用扩展

4.1 返回键处理

WillPopScope(
  onWillPop: () async {
    if (await _controller?.canGoBack() ?? false) {
      _controller?.goBack();
      return false;
    }
    return true;
  },
  child: AppWebView(url: url),
)

4.2 白名单拦截

final allowHosts = {'example.com'};
if (!allowHosts.contains(uri.host)) return NavigationActionPolicy.CANCEL;

5. 常见坑点

  • 返回键未处理:用户体验差
  • HTTP 资源加载失败:需要平台安全配置
  • JS 通信名不一致:handlerName 必须统一

6. 实践清单

  • 统一封装
  • 加载状态
  • URL 拦截
  • JS 通信

JJ

作者简介

专注于内容创作、产品策略与设计实践。欢迎交流合作。

上一篇 下一篇