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版本使用

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

相关推荐
2601_9498477515 分钟前
Flutter for OpenHarmony 剧本杀组队App实战:邀请好友功能实现
开发语言·javascript·flutter
2601_9498683635 分钟前
Flutter for OpenHarmony 电子合同签署App实战 - 数据持久化实现
java·数据库·flutter
ITUnicorn1 小时前
Flutter x HarmonyOS 6:依托小艺开放平台创建智能体并在应用中调用
flutter·harmonyos·鸿蒙·智能体·harmonyos6
子春一1 小时前
Flutter for OpenHarmony: 从颜色模型到可访问性:一个 Flutter 高对比度 UI 的完整实践
flutter·ui
小白郭莫搞科技2 小时前
鸿蒙跨端框架Flutter学习:CurvedAnimation曲线动画详解
学习·flutter·harmonyos
一起养小猫2 小时前
Flutter for OpenHarmony 实战:ListView与GridView滚动列表完全指南
开发语言·javascript·flutter
程序员清洒2 小时前
Flutter for OpenHarmony:ListView — 高效滚动列表
开发语言·flutter·华为·鸿蒙
Miguo94well2 小时前
Flutter框架跨平台鸿蒙开发——旅行攻略规划APP的开发流程
flutter·华为·harmonyos·鸿蒙
zilikew2 小时前
Flutter框架跨平台鸿蒙开发——食物采购清单APP的开发流程
flutter·华为·harmonyos·鸿蒙
晚霞的不甘3 小时前
Flutter for OpenHarmony《智慧字典》 App 主页深度优化解析:从视觉动效到交互体验的全面升级
前端·flutter·microsoft·前端框架·交互