Flutter 学习之旅 之 flutter 使用 webview_flutter 进行网页显示的 传入URL、返回、标题、加载开始、加载完成的 接口的简单封装类
目录
Flutter 学习之旅 之 flutter 使用 webview_flutter 进行网页显示的 传入URL、返回、标题、加载开始、加载完成的 接口的简单封装类
一、简单介绍
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. 调试和日志
在开发过程中,可以使用
三、安装 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
);
}
}
代码说明
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
显示网页内容。