flutter开发实战-webview_flutter 4.x版本使用

flutter开发实战-webview_flutter 4.x版本使用

在之前使用的webview_flutter版本是3.x的,升级到4.x后,使用方式有所变化。

一、webview_flutter

在工程的pubspec.yaml中引入插件

  webview_flutter: ^4.4.2

二、使用webview_flutter

在4.x版本中,我们使用WebViewController来监听加载的状态

代码如下

controller
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setBackgroundColor(const Color(0x00000000))
      ..setNavigationDelegate(
        NavigationDelegate(
          onProgress: (int progress) {
            debugPrint('WebView is loading (progress : $progress%)');
          },
          onPageStarted: (String url) {
            debugPrint('Page started loading: $url');
          },
          onPageFinished: (String url) {
            debugPrint('Page finished loading: $url');
          },
          onWebResourceError: (WebResourceError error) {
            debugPrint('''
Page resource error:
  code: ${error.errorCode}
  description: ${error.description}
  errorType: ${error.errorType}
  isForMainFrame: ${error.isForMainFrame}
          ''');
          },
          onNavigationRequest: (NavigationRequest request) {
            if (request.url.startsWith('https://') ||
                request.url.startsWith('http://')) {
              return NavigationDecision.navigate;
            }
            return NavigationDecision.prevent;
          },
          onUrlChange: (UrlChange change) {
            debugPrint('url change to ${change.url}');
          },
          // onHttpAuthRequest: (HttpAuthRequest request) {
          //   openDialog(request);
          // },
        ),
      )
      ..addJavaScriptChannel(
        'Toaster',
        onMessageReceived: (JavaScriptMessage message) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text(message.message)),
          );
        },
      )
      ..loadRequest(Uri.parse('https://baidu.com'));

    // #docregion platform_features
    if (controller.platform is AndroidWebViewController) {
      AndroidWebViewController.enableDebugging(true);
      (controller.platform as AndroidWebViewController)
          .setMediaPlaybackRequiresUserGesture(false);
    }
    // #enddocregion platform_features

    _controller = controller;

注意这个addJavaScriptChannel,之前3.x版本中有一个JavaScriptChannel类,在4.x版本中没有了。

这个JavaScriptChannel可以方便实现与JS的交互

dart 复制代码
final WebViewController controller = WebViewController();
controller.addJavaScriptChannel(
  'Print',
  onMessageReceived: (JavaScriptMessage message) {
    print(message.message);
  },
);

JavaScript可以这样调用:

javascript 复制代码
Print.postMessage('Hello');

我们为了方便JS与flutter调用,需要改造一下。使用JSBridge实现逻辑来嵌套使用该JavaScriptChannel

4.x版本使用完整代码如下

// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// ignore_for_file: public_member_api_docs

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:webview_flutter/webview_flutter.dart';

// #docregion platform_imports
// Import for Android features.
import 'package:webview_flutter_android/webview_flutter_android.dart';

// Import for iOS features.
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
// #enddocregion platform_imports

class WebViewPage extends StatefulWidget {
  const WebViewPage({super.key});

  @override
  State<WebViewPage> createState() => _WebViewPageState();
}

class _WebViewPageState extends State<WebViewPage> {
  late final WebViewController _controller;

  @override
  void initState() {
    super.initState();

    // #docregion platform_features
    late final PlatformWebViewControllerCreationParams params;
    if (WebViewPlatform.instance is WebKitWebViewPlatform) {
      params = WebKitWebViewControllerCreationParams(
        allowsInlineMediaPlayback: true,
        mediaTypesRequiringUserAction: const <PlaybackMediaTypes>{},
      );
    } else {
      params = const PlatformWebViewControllerCreationParams();
    }

    final WebViewController controller =
        WebViewController.fromPlatformCreationParams(params);
    // #enddocregion platform_features

    controller
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setBackgroundColor(const Color(0x00000000))
      ..setNavigationDelegate(
        NavigationDelegate(
          onProgress: (int progress) {
            debugPrint('WebView is loading (progress : $progress%)');
          },
          onPageStarted: (String url) {
            debugPrint('Page started loading: $url');
          },
          onPageFinished: (String url) {
            debugPrint('Page finished loading: $url');
          },
          onWebResourceError: (WebResourceError error) {
            debugPrint('''
Page resource error:
  code: ${error.errorCode}
  description: ${error.description}
  errorType: ${error.errorType}
  isForMainFrame: ${error.isForMainFrame}
          ''');
          },
          onNavigationRequest: (NavigationRequest request) {
            if (request.url.startsWith('https://') ||
                request.url.startsWith('http://')) {
              return NavigationDecision.navigate;
            }
            return NavigationDecision.prevent;
          },
          onUrlChange: (UrlChange change) {
            debugPrint('url change to ${change.url}');
          },
          // onHttpAuthRequest: (HttpAuthRequest request) {
          //   openDialog(request);
          // },
        ),
      )
      ..addJavaScriptChannel(
        'Toaster',
        onMessageReceived: (JavaScriptMessage message) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text(message.message)),
          );
        },
      )
      ..loadRequest(Uri.parse('https://baidu.com'));

    // #docregion platform_features
    if (controller.platform is AndroidWebViewController) {
      AndroidWebViewController.enableDebugging(true);
      (controller.platform as AndroidWebViewController)
          .setMediaPlaybackRequiresUserGesture(false);
    }
    // #enddocregion platform_features

    _controller = controller;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.green,
      appBar: AppBar(
        title: const Text('Flutter WebView example'),
        // This drop down menu demonstrates that Flutter widgets can be shown over the web view.
      ),
      body: WebViewWidget(controller: _controller),
    );
  }
}

三、小结

flutter开发实战-webview_flutter 4.x版本使用

学习记录,每天不停进步。

相关推荐
字节全栈_rJF1 天前
Flutter Candies 一桶天下
前端·javascript·flutter
pengyu1 天前
系统化掌握 Dart 编程之异常处理(二):从防御到艺术的进阶之路
android·flutter·dart
字节全栈_ZKt2 天前
FIDL:Flutter与原生通讯的新姿势,不局限于基础数据类型
flutter
小龙在山东2 天前
Flutter开发环境配置
flutter
字节全栈_ZKt2 天前
微店的Flutter混合开发组件化与工程化架构
flutter·架构·蓝桥杯
earthzhang20213 天前
《深入浅出HTTPS》读书笔记(31):HTTPS和TLS/SSL
开发语言·网络·python·https·1024程序员节
恋猫de小郭3 天前
Flutter 新春第一弹,Dart 宏功能推进暂停,后续专注定制数据处理支持
android·java·flutter
LuiChun3 天前
webview_flutter_wkwebview3.17.0 --Cookie认证
flutter
smart_ljh5 天前
国内flutter环境部署(记录篇)
flutter
LuiChun5 天前
Flutter中使用WebView加载html页面时下载js_css文件的流程
flutter