Flutter 学习之旅 之 flutter 使用 webview
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 的初始化
在 _WebViewPageState 的 initState 方法中,初始化了一个 WebViewController,并配置了以下内容:
-
setJavaScriptMode: 设置 JavaScript 模式为 JavaScriptMode.unrestricted,允许网页运行 JavaScript。
-
loadRequest: 加载传入的 URL。
-
setNavigationDelegate: 设置导航代理,监听网页加载的各个阶段:
-
onPageStarted: 网页开始加载时调用 onWebViewCreated 回调。
-
onPageFinished: 网页加载完成时调用 onWebViewLoaded 回调。
-
onProgress: 网页加载进度发生变化时调用 onWebViewProgress 回调。
-
onHttpError: 网页加载发生 HTTP 错误时调用 onWebViewError 回调,并显示 SnackBar 提示加载失败。
3. build 方法
在 _WebViewPageState 的 build 方法中,返回了一个 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
在 _WebViewPageState 的 initState 方法中初始化 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. 处理返回按钮
在 AppBar 的 leading 属性中添加返回按钮,并在点击时调用 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 { 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 ); } }
代码说明
-
MyApp:
-
应用的入口点,返回一个 MaterialApp,设置首页为 HomeScreen。
-
HomeScreen:
-
首页包含一个按钮,点击按钮后跳转到 WebViewPage。
-
通过 Navigator.push 传入 WebViewPage 所需的参数,包括 URL、标题、返回事件、网页开始加载事件、网页加载完成事件、网页加载进度事件和网页加载错误事件。
-
WebViewPage:
-
一个有状态的小部件,用于显示网页。
-
包含以下参数:
-
url: 网页的 URL。
-
title: 网页的标题。
-
onBack: 返回事件的回调。
-
onWebViewCreated: 网页开始加载的回调。
-
onWebViewLoaded: 网页加载完成的回调。
-
onWebViewProgress: 网页加载进度的回调(可选)。
-
onWebViewError: 网页加载错误的回调(可选)。
-
_WebViewPageState:
-
初始化 WebViewController,设置允许执行 JavaScript,并加载传入的 URL。
-
使用 NavigationDelegate 监听网页加载的各个阶段:
-
onPageStarted: 网页开始加载时调用 onWebViewCreated。
-
onPageFinished: 网页加载完成时调用 onWebViewLoaded。
-
onProgress: 网页加载进度发生变化时调用 onWebViewProgress。
-
onHttpError: 网页加载发生 HTTP 错误时调用 onWebViewError,并显示 SnackBar 提示加载失败。
-
WebViewWidget:
-
使用 WebViewWidget 显示网页内容。
-
-
-
-
-
-
-
-
-
-
-
-
-
-