flutter开发实战-webview插件flutter_inappwebview使用
在开发过程中,经常遇到需要使用WebView,Webview需要调用原生的插件来实现。常见的flutter的webview插件是webview_flutter,flutter_inappwebview。之前整理了一下webview_flutter,查看
https://blog.csdn.net/gloryFlow/article/details/131683122
这里我们使用flutter_inappwebview来加载网页。
使用flutter_inappwebview,需要在pubspec.yaml引入插件。
# 浏览器
flutter_inappwebview: 5.4.3+7
使用flutter_inappwebview插件前,我们先看下flutter_inappwebview提供的webview的属性
WebView(
{this.windowId,
this.onWebViewCreated,
this.onLoadStart,
this.onLoadStop,
this.onLoadError,
this.onLoadHttpError,
this.onProgressChanged,
this.onConsoleMessage,
this.shouldOverrideUrlLoading,
this.onLoadResource,
this.onScrollChanged,
@Deprecated('Use `onDownloadStartRequest` instead')
this.onDownloadStart,
this.onDownloadStartRequest,
this.onLoadResourceCustomScheme,
this.onCreateWindow,
this.onCloseWindow,
this.onJsAlert,
this.onJsConfirm,
this.onJsPrompt,
this.onReceivedHttpAuthRequest,
this.onReceivedServerTrustAuthRequest,
this.onReceivedClientCertRequest,
this.onFindResultReceived,
this.shouldInterceptAjaxRequest,
this.onAjaxReadyStateChange,
this.onAjaxProgress,
this.shouldInterceptFetchRequest,
this.onUpdateVisitedHistory,
this.onPrint,
this.onLongPressHitTestResult,
this.onEnterFullscreen,
this.onExitFullscreen,
this.onPageCommitVisible,
this.onTitleChanged,
this.onWindowFocus,
this.onWindowBlur,
this.onOverScrolled,
this.onZoomScaleChanged,
this.androidOnSafeBrowsingHit,
this.androidOnPermissionRequest,
this.androidOnGeolocationPermissionsShowPrompt,
this.androidOnGeolocationPermissionsHidePrompt,
this.androidShouldInterceptRequest,
this.androidOnRenderProcessGone,
this.androidOnRenderProcessResponsive,
this.androidOnRenderProcessUnresponsive,
this.androidOnFormResubmission,
@Deprecated('Use `onZoomScaleChanged` instead')
this.androidOnScaleChanged,
this.androidOnReceivedIcon,
this.androidOnReceivedTouchIconUrl,
this.androidOnJsBeforeUnload,
this.androidOnReceivedLoginRequest,
this.iosOnWebContentProcessDidTerminate,
this.iosOnDidReceiveServerRedirectForProvisionalNavigation,
this.iosOnNavigationResponse,
this.iosShouldAllowDeprecatedTLS,
this.initialUrlRequest,
this.initialFile,
this.initialData,
this.initialOptions,
this.contextMenu,
this.initialUserScripts,
this.pullToRefreshController,
this.implementation = WebViewImplementation.NATIVE});
列一下常用的几个
- initialUrlRequest:加载url的请求
- initialUserScripts:初始化设置的script
- initialOptions:初始化设置的配置
- onWebViewCreated:webview创建后的callback回调
- onTitleChanged:网页title变换的监听回调
- onLoadStart:网页开始加载
- shouldOverrideUrlLoading:确定路由是否可以替换,比如可以控制某些连接不允许跳转。
- onLoadStop:网页加载结束
- onProgressChanged:页面加载进度progress
- onLoadError:页面加载失败
- onUpdateVisitedHistory;更新访问的历史页面回调
- onConsoleMessage:控制台消息,用于输出console.log信息
使用WebView加载网页
class WebViewInAppScreen extends StatefulWidget {
const WebViewInAppScreen({
Key? key,
required this.url,
this.onWebProgress,
this.onWebResourceError,
required this.onLoadFinished,
required this.onWebTitleLoaded,
this.onWebViewCreated,
}) : super(key: key);
final String url;
final Function(int progress)? onWebProgress;
final Function(String? errorMessage)? onWebResourceError;
final Function(String? url) onLoadFinished;
final Function(String? webTitle)? onWebTitleLoaded;
final Function(InAppWebViewController controller)? onWebViewCreated;
@override
State<WebViewInAppScreen> createState() => _WebViewInAppScreenState();
class _WebViewInAppScreenState extends State<WebViewInAppScreen> {
final GlobalKey webViewKey = GlobalKey();
InAppWebViewController? webViewController;
InAppWebViewOptions viewOptions = InAppWebViewOptions(
useShouldOverrideUrlLoading: true,
mediaPlaybackRequiresUserGesture: true,
applicationNameForUserAgent: "dface-yjxdh-webview",
@override
void initState() {
super.initState();
@override
void dispose() {
webViewController?.clearCache();
super.dispose();
void setWebPageTitle(data) {
if (widget.onWebTitleLoaded != null) {
widget.onWebTitleLoaded!(data);
void callJSMethod() {
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Expanded(
child: InAppWebView(
key: webViewKey,
initialUrlRequest: URLRequest(url: Uri.parse(widget.url)),
initialUserScripts: UnmodifiableListView<UserScript>([
UserScript(
source:
"document.cookie='token=${ApiAuth().token};domain='.laileshuo.cb';path=/'",
injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START),
]),
initialOptions: InAppWebViewGroupOptions(
crossPlatform: viewOptions,
onWebViewCreated: (controller) {
webViewController = controller;
if (widget.onWebViewCreated != null) {
widget.onWebViewCreated!(controller);
onTitleChanged: (controller, title) {
if (widget.onWebTitleLoaded != null) {
widget.onWebTitleLoaded!(title);
onLoadStart: (controller, url) {},
shouldOverrideUrlLoading: (controller, navigationAction) async {
return NavigationActionPolicy.ALLOW;
onLoadStop: (controller, url) async {
widget.onLoadFinished(url.toString());
onProgressChanged: (controller, progress) {
if (widget.onWebProgress != null) {
widget.onWebProgress!(progress);
onLoadError: (controller, Uri? url, int code, String message) {
if (widget.onWebResourceError != null) {
widget.onWebResourceError!(message);
onUpdateVisitedHistory: (controller, url, androidIsReload) {},
onConsoleMessage: (controller, consoleMessage) {
print(consoleMessage);
Container(
height: ScreenUtil().bottomBarHeight + 50.0,
color: Colors.white,
child: Column(
children: [
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
ElevatedButton(
child: Icon(Icons.arrow_back),
onPressed: () {
webViewController?.goBack();
SizedBox(
width: 25.0,
ElevatedButton(
child: Icon(Icons.arrow_forward),
onPressed: () {
webViewController?.goForward();
SizedBox(
width: 25.0,
ElevatedButton(
child: Icon(Icons.refresh),
onPressed: () {
webViewController?.reload();
Container(
height: ScreenUtil().bottomBarHeight,
flutter开发实战-webview插件flutter_inappwebview使用。描述可能不准确,请见谅。
https://blog.csdn.net/gloryFlow/article/details/133489866
学习记录,每天不停进步。
Dart SDK:“> = 2.7.0 <3> = 1.12.13 + hotfix.5”
Android: minSdkVersion 17并添加了对androidx支持(请参阅以迁移现有应用)
iOS:-- --ios-language swift ,Xcode版本>= 11
适用于Android和iOS的重要说明
如果您正在运行应用程序,并且需要在runApp()之前runApp()例如,在插件初始化期间runApp()访问二进制Messenger,则需要首先显式调用WidgetsFlutterBinding.ensureInitialized() 。
一个例子:
Dart SDK:“> = 2.12.0-0 <3> = 1.22.0”
Android: minSdkVersion 17并添加了对androidx支持(请参阅以迁移现有应用)
iOS:-- --ios-language swift ,Xcode版本>= 11
适用于Android和iOS的重要说明
如果您正在运行应用程序,并且需要在runApp()之前runApp()例如,在插件初始化期间runApp()访问二进制Messenger,则需要首先显式调用WidgetsFlutterBinding.ensureInitialized() 。
一个例子:
void main () {
// it should be the first line in main method
WidgetsFlutterBinding . ensureInitialized ();
// rest of y
Flutter浏览器应用
使用Flutter和插件提供的功能创建的全功能移动浏览器应用(例如Google Chrome移动浏览器)。
可在Google Play商店中找到它, 为
文章: 。
还可以在此处查看介绍插件的文章: 。
WebView选项卡,具有在长按链接/图像预览时自定义的功能,以及如何在不丢失WebView状态的情况下从一个选项卡移动到另一个选项卡;
具有当前URL和所有弹出菜单操作的浏览器应用栏,例如打开新标签页,新的隐身标签页,将当前URL保存到收藏夹列表,将页面保存为脱机使用,查看网站使用的SSL证书,启用桌面模式等(功能类似于Google Chrome应用);
开发人员控制台,您可以在其中执行JavaScript代码,查看一些网络信息,管理浏览器存储(例如Cookie,window.localStorage等);
设置页面,您可以在其中更新浏览
webview_flutter 是官方维护的 WebView 插件,特性是基于原生和 Flutter SDK 封装,继承 StatefulWidget,因此支持内嵌于 Flutter Widget 树中,这是比较灵活的。但不支持https自制证书强制信任。
flutter_webview_plugin 则是基于原生 WebView 封装的 Flutter 插件,将原生的一些基本使用 API 封装好提供给 Flutter 调用,因此并不能内嵌于 Flutter Widget ...
要在Flutter中实现在`flutter_inappwebview`中更改应用程序栏标题,您需要使用`InAppWebViewController`的`shouldOverrideUrlLoading`方法。该方法在Web视图中的任何导航期间调用,在此期间您可以获取导航的URL并相应地更新应用程序栏标题。
下面是一个简单的例子:
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
class MyInAppWebView extends StatefulWidget {
@override
_MyInAppWebViewState createState() => _MyInAppWebViewState();
class _MyInAppWebViewState extends State<MyInAppWebView> {
InAppWebViewController _webViewController;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My App'),
body: InAppWebView(
initialUrl: 'https://www.example.com',
onWebViewCreated: (InAppWebViewController controller) {
_webViewController = controller;
shouldOverrideUrlLoading: (controller, navigationAction) async {
var url = navigationAction.request.url;
if (url.contains('example.com')) {
setState(() {
// 更新应用程序栏标题
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Loading ' + url),
duration: Duration(seconds: 1),
AppBar(
title: Text('New Title'),
return NavigationActionPolicy.ALLOW;
return NavigationActionPolicy.ALLOW;
在上面的代码中,我们使用一个名为`shouldOverrideUrlLoading`的回调来捕获Web视图中的任何导航,并检查URL是否包含`example.com`。如果是,则我们更新应用程序栏标题。我们使用`setState`方法来更新标题,并使用`ScaffoldMessenger`来显示一个短暂的消息,以通知用户正在加载新页面。