Flutter 学习之旅 之 flutter 使用 webview_flutter 进行网页显示的 传入URL、返回、标题、加载开始、加载完成的 接口的简单封装类

Flutter 学习之旅 之 flutter 使用 webview_flutter 进行网页显示的 传入URL、返回、标题、加载开始、加载完成的 接口的简单封装类

目录

Flutter 学习之旅 之 flutter 使用 webview_flutter 进行网页显示的 传入URL、返回、标题、加载开始、加载完成的 接口的简单封装类

一、简单介绍

二、webview

WebViewPage 实现原理

使用 WebViewPage 的注意事项

三、安装 webview_flutter

四、简单效果

五、简单案例实现

六、关键代码


一、简单介绍

Flutter 是一款开源的 UI 软件开发工具包,由 Google 开发和维护。它允许开发者使用一套代码同时构建跨平台的应用程序,包括移动设备(iOS 和 Android)、Web 和桌面平台(Windows、macOS 和 Linux)。

Flutter 使用 Dart 编程语言,它可以将代码编译为 ARM 或 Intel 机器代码以及 JavaScript,从而实现快速的性能。Flutter 提供了一个丰富的预置小部件库,开发者可以根据自己的需求灵活地控制每个像素,从而创建自定义的、适应性强的设计,这些设计在任何屏幕上都能呈现出色的外观和感觉。

二、webview

网址:webview_flutter | Flutter package

webview_flutter 是 Flutter 官方提供的一个跨平台 WebView 插件,用于在 Flutter 应用中嵌入网页内容。它基于 Android 的 WebView 和 iOS 的 WKWebView 实现,支持多平台(包括 Android 和 iOS),并提供了丰富的功能。

WebViewPage 实现原理

WebViewPage 是一个封装了 webview_flutter 插件的 Flutter 小部件,用于在 Flutter 应用中嵌入一个网页视图。以下是其实现原理的详细说明:

1. WebViewPage 的构造函数

WebViewPage 的构造函数定义了以下参数:

  • url: 要加载的网页的 URL。

  • title: 网页的标题,显示在标题栏中。

  • onBack: 返回按钮的回调函数,通常用于返回到上一个页面。

  • onWebViewCreated: 网页开始加载时的回调函数。

  • onWebViewLoaded: 网页加载完成时的回调函数。

  • onWebViewProgress: 网页加载进度的回调函数(可选)。

  • onWebViewError: 网页加载失败时的回调函数(可选)。

这些参数允许调用者在不同的事件发生时执行自定义逻辑。

2. _WebViewPageState 的初始化

_WebViewPageStateinitState 方法中,初始化了一个 WebViewController,并配置了以下内容:

  • setJavaScriptMode: 设置 JavaScript 模式为 JavaScriptMode.unrestricted,允许网页运行 JavaScript。

  • loadRequest: 加载传入的 URL。

  • setNavigationDelegate: 设置导航代理,监听网页加载的各个阶段:

    • onPageStarted: 网页开始加载时调用 onWebViewCreated 回调。

    • onPageFinished: 网页加载完成时调用 onWebViewLoaded 回调。

    • onProgress: 网页加载进度发生变化时调用 onWebViewProgress 回调。

    • onHttpError: 网页加载发生 HTTP 错误时调用 onWebViewError 回调,并显示 SnackBar 提示加载失败。

3. build 方法

_WebViewPageStatebuild 方法中,返回了一个 Scaffold,包含:

  • AppBar: 标题栏,显示传入的标题,并在左边添加了一个返回按钮。

  • WebViewWidget: 显示网页内容,使用 _controller 控制网页视图。

使用 WebViewPage 的注意事项

1. 依赖管理

确保在 pubspec.yaml 文件中正确添加了 webview_flutter 的依赖,并运行 flutter pub get

yaml复制

dependencies:
  flutter:
    sdk: flutter
  webview_flutter: ^4.0.0

2. 初始化 WebViewController

_WebViewPageStateinitState 方法中初始化 WebViewController,确保在页面加载时正确配置 WebView

3. 监听网页加载事件

通过 setNavigationDelegate 监听网页加载的各个阶段:

  • onPageStarted: 网页开始加载时调用。

  • onPageFinished: 网页加载完成时调用。

  • onProgress: 网页加载进度发生变化时调用。

  • onHttpError: 网页加载发生 HTTP 错误时调用。

4. 检查上下文有效性

在调用 ScaffoldMessenger.of(context) 时,确保上下文是有效的。如果在异步操作中调用,可以使用 mounted 属性检查当前的上下文是否仍然有效:

dart复制

if (mounted) {
  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(content: Text('加载失败: ${error}')),
  );
}

5. 处理返回按钮

AppBarleading 属性中添加返回按钮,并在点击时调用 onBack 回调。通常,onBack 回调会调用 Navigator.pop(context),返回到上一个页面。

6. 加载进度和错误处理

  • 加载进度:通过 onProgress 回调可以显示加载进度,例如使用一个进度条。

  • 加载错误:通过 onHttpError 回调可以捕获加载错误,并给用户友好的提示。

7. 平台特定配置

  • iOS:确保在 Info.plist 中正确配置了网络访问权限。

  • Android:确保 minSdkVersion 设置为 20 或更高。

8. 调试和日志

在开发过程中,可以使用 print 打印日志,帮助调试和了解网页加载的状态。

三、安装 webview_flutter

1、直接运行命令

使用 Flutter:flutter pub add webview_flutter

2、或者在 pubspec.yaml 添加

dependencies: 
   webview_flutter: ^4.10.0

四、简单效果

五、简单案例实现

1、这里使用 Android Studio 进行创建 Flutter 项目

2、创建一个 application 的 Flutter 项目

3、项目结构如下

4、使用 webview_flutter  编写网页显示功能

5、连接设备,运行效果如下

六、关键代码

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

void main() {
  runApp(MyApp());
}

// 定义一个无状态的小部件,作为应用的入口点
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 返回一个 MaterialApp,设置应用的首页为 HomeScreen
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

// 定义一个无状态的小部件,作为应用的首页
class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 返回一个 Scaffold,包含一个 AppBar 和一个 Center 包裹的 ElevatedButton
    return Scaffold(
      appBar: AppBar(
        title: Text('WebView 示例'), // 设置标题栏的标题
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // 定义按钮的点击事件,跳转到 WebView 页面
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => WebViewPage(
                  url: 'https://www.deepseek.com/', // 传入的 URL
                  title: 'DeepSeek', // 传入的标题
                  onBack: () {
                    // 定义返回事件,返回到上一个页面
                    Navigator.pop(context);
                  },
                  onWebViewCreated: () {
                    // 定义网页开始加载事件
                    ScaffoldMessenger.of(context).showSnackBar(
                      SnackBar(content: Text('网页开始加载...')), // 显示 SnackBar 提示
                    );
                    print("onWebViewCreated "); // 打印日志
                  },
                  onWebViewLoaded: () {
                    // 定义网页加载完成事件
                    ScaffoldMessenger.of(context).showSnackBar(
                      SnackBar(content: Text('网页加载完成!')), // 显示 SnackBar 提示
                    );
                    print("onWebViewLoaded "); // 打印日志
                  },
                  onWebViewProgress: (int progress) {
                    // 定义网页加载进度事件
                    print("onWebViewProgress progress $progress"); // 打印日志
                  },
                  onWebViewError: (HttpResponseError error) {
                    // 定义网页加载错误事件
                    ScaffoldMessenger.of(context).showSnackBar(
                      SnackBar(content: Text('加载失败: ${error}')), // 显示 SnackBar 提示
                    );
                    print("onWebViewError "); // 打印日志
                  },
                ),
              ),
            );
          },
          child: Text('打开网页'), // 设置按钮的文本
        ),
      ),
    );
  }
}

// 定义一个有状态的小部件,用于显示 WebView 页面
class WebViewPage extends StatefulWidget {
  final String url; // 网页的 URL
  final String title; // 网页的标题
  final VoidCallback onBack; // 返回事件的回调
  final VoidCallback onWebViewCreated; // 网页开始加载的回调
  final VoidCallback onWebViewLoaded; // 网页加载完成的回调
  final Function(int)? onWebViewProgress; // 网页加载进度的回调
  final Function(HttpResponseError)? onWebViewError; // 网页加载错误的回调

  // 构造函数,初始化各个参数
  const WebViewPage({
    Key? key,
    required this.url,
    required this.title,
    required this.onBack,
    required this.onWebViewCreated,
    required this.onWebViewLoaded,
    this.onWebViewProgress,
    this.onWebViewError,
  }) : super(key: key);

  @override
  _WebViewPageState createState() => _WebViewPageState();
}

// 定义 WebViewPage 的状态类
class _WebViewPageState extends State<WebViewPage> {
  late WebViewController _controller; // 声明一个 WebViewController 对象

  @override
  void initState() {
    super.initState();
    // 初始化 WebViewController
    _controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted) // 设置允许执行 JavaScript
      ..loadRequest(Uri.parse(widget.url)) // 加载传入的 URL
      ..setNavigationDelegate(
        NavigationDelegate(
          onPageStarted: (String url) {
            // 当网页开始加载时,调用 onWebViewCreated 回调
            widget.onWebViewCreated();
          },
          onPageFinished: (String url) {
            // 当网页加载完成时,调用 onWebViewLoaded 回调
            widget.onWebViewLoaded();
          },
          onProgress: (int progress) {
            // 当网页加载进度发生变化时,调用 onWebViewProgress 回调
            widget.onWebViewProgress?.call(progress);
          },
          onHttpError: (HttpResponseError error) {
            // 当网页加载发生 HTTP 错误时,调用 onWebViewError 回调
            widget.onWebViewError?.call(error);

            // 显示 SnackBar 提示加载失败
            if (mounted) {
              ScaffoldMessenger.of(context).showSnackBar(
                SnackBar(
                  content: Text('加载失败: ${error}'), // 显示错误信息
                  duration: Duration(seconds: 2), // 设置显示时长
                ),
              );
            }
          },
        ),
      );
  }

  @override
  Widget build(BuildContext context) {
    // 返回一个 Scaffold,包含一个 AppBar 和一个 WebViewWidget
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title, textAlign: TextAlign.center), // 设置标题栏的标题
        centerTitle: true, // 标题居中
        leading: IconButton(
          icon: Icon(Icons.arrow_back), // 设置返回按钮的图标
          onPressed: widget.onBack, // 设置返回按钮的点击事件
        ),
      ),
      body: WebViewWidget(controller: _controller), // 显示 WebView
    );
  }
}

代码说明

  1. MyApp:

    • 应用的入口点,返回一个 MaterialApp,设置首页为 HomeScreen

  2. HomeScreen:

    • 首页包含一个按钮,点击按钮后跳转到 WebViewPage

    • 通过 Navigator.push 传入 WebViewPage 所需的参数,包括 URL、标题、返回事件、网页开始加载事件、网页加载完成事件、网页加载进度事件和网页加载错误事件。

  3. WebViewPage:

    • 一个有状态的小部件,用于显示网页。

    • 包含以下参数:

      • url: 网页的 URL。

      • title: 网页的标题。

      • onBack: 返回事件的回调。

      • onWebViewCreated: 网页开始加载的回调。

      • onWebViewLoaded: 网页加载完成的回调。

      • onWebViewProgress: 网页加载进度的回调(可选)。

      • onWebViewError: 网页加载错误的回调(可选)。

  4. _WebViewPageState:

    • 初始化 WebViewController,设置允许执行 JavaScript,并加载传入的 URL。

    • 使用 NavigationDelegate 监听网页加载的各个阶段:

      • onPageStarted: 网页开始加载时调用 onWebViewCreated

      • onPageFinished: 网页加载完成时调用 onWebViewLoaded

      • onProgress: 网页加载进度发生变化时调用 onWebViewProgress

      • onHttpError: 网页加载发生 HTTP 错误时调用 onWebViewError,并显示 SnackBar 提示加载失败。

  5. WebViewWidget:

    • 使用 WebViewWidget 显示网页内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仙魁XAN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值