flutter层不支持webview,加载网页的功能还需要借助控件来处理。

通过pub.dev搜索以及对比网上文章,发现了几个比较受欢迎的flutter webview插件;

这三种插件对比图(此图借鉴自网络)

这里详细介绍使用flutter_inappwebview5.3.2版本插件完成交互;

注意:flutter_inappwebview6.xx 版本flutter3.0以下不支持;

控件地址:https://pub.dev/packages/flutter_inappwebview。

1.安装插件

1)在配置文件pubbspec.yaml中加 flutter_inappwebview: 5.3.2;然后运行flutter pub get同步插件;

flutter_inappwebview: 5.3.2

2.配置

1)在入口文件main.dart中加入

// 不加这个强制横/竖屏会报错

WidgetsFlutterBinding.ensureInitialized();

3.主要类概览

该插件主要提供了以下类:

InAppWebView :一个 Flutter 小部件,用于添加整合到 Flutter 部件树的内联原生 WebView。

ContextMenu :该类表示 WebView 的快捷菜单。

HeadlessInAppWebView :该类表示处于 headless 模式的 WebView。它可以用来在后台运行 WebView,而无需将 InAppWebView 附加到部件树中。

InAppBrowser :使用原生 WebView 的 In-App Browser。

ChromeSafariBrowser :使用 Chrome Custom Tabs (Android)和 SFSafariViewController (iOS)的 In-App Browser。

InAppLocalhostServer :该类让你可以创建一个简单的服务器: http://localhost:[port]/ . ,默认 port 为 8080 。

CookieManager :这个类实现了一个单例对象(共享实例),管理 WebView 实例使用的 cookie。

HttpAuthCredentialDatabase :该类实现一个管理共享 HTTP 身份验证凭据缓存的单例对象(共享实例)。

WebStorageManager :该类生成一个管理 Web 存储(供 WebView 实例使用)的单例对象(共享实例)。

......

4.使用

(1)加载webview视图

1)展示一个url的视图内容

flutter代码如下:

app上呈现的效果图:

2) 展示一个html视图内容

html代码如下:

flutter代码:

在app上呈现的效果:

3)在flutter代码中处理你url文件或html文件的某个demo结构

以html文件为例,我想要在箭头所指的demo结构处添加文字内容“12345678910”和一些样式

那么在flutter代码中添加

//在InAppWebView配置项中添加

onPageCommitVisible: (inAppWebViewControlle, uri) async {

//_loadPage是声明的一个全局bool类型变量

if (_loadPage) {

setState(() {

_loadPage = false;

});

//获取到webview的所有html结构

var fileHtmlContents = await webViewController!.getHtml();

//找到带有某种唯一标识的demo结构并替换它

fileHtmlContents = fileHtmlContents!.replaceAll(

'

',

"

12345678910
",

);

//重新渲染结构

webViewController!.loadData(data: fileHtmlContents);

}

},

效果:

(2)与js交互传参

在flutter代码中添加

//添加在InAppWebView配置项里

// InAppWebview中获取InAppWebViewController

onWebViewCreated: (InAppWebViewController controller) {

// 注册一个JS处理方法,名称为myHandlerName

controller.addJavaScriptHandler(

handlerName: 'myHandlerName',

callback: (args) {

// 打印js方传递过来的参数

print('args=js方传递过来的参数============================$args');

// 传给js方的参数

// 可以传递你所需要的任意类型数据,数组、对象等

return "flutter给js的数据";

});

},

//这个方法可以打印js中的conse.log内容

onConsoleMessage: (controller, consoleMessage) {

//这里是打印来自于js的conse.log打印

print("consoleMessage==来自于js的打印====$consoleMessage");

},

在js代码中添加

// 下面的"flutterInAppWebViewPlatformReady"为固定写法

// "myHandlerName"与flutter中注册的JS处理方法名称一致

window.addEventListener("flutterInAppWebViewPlatformReady", function () {

window.flutter_inappwebview

//可以传递你所需要的任意类型数据,数组、对象等

.callHandler("myHandlerName", "这里是传给flutter的参数")

.then(function (res) {

console.log("res========flutter给html的数据", res);

})

})

flutter控制台输出:

传递数据成功啦,可以开始你对这些数据的处理啦。

注意:每次修改了html文件代码都需要终止flutter项目进程重新启动,否则你将看不到你的改动效果。

(3)完整demo代码

flutter代码

import 'package:flutter/cupertino.dart';

import 'package:flutter_inappwebview/flutter_inappwebview.dart';

class HomePage extends StatefulWidget {

HomePage({Key? key, required this.url}) : super(key: key);

String url;

@override

State createState() => _HomePageState();

}

class _HomePageState extends State {

bool _loadPage = true;

InAppWebViewController? webViewController;

// GlobalKey可以获取到对应的Widget的State对象!

// 当我们页面内容很多时,而需要改变的内容只有很少的一部分且在树的底层的时候,我们如何去实现增量更新?

// 通常情况下有两种方式,第一种是通过方法的回调,去实现数据更新,第二种是通过GlobalKey,

final GlobalKey webViewKey = GlobalKey();

// webview配置

InAppWebViewGroupOptions options = InAppWebViewGroupOptions(

// 跨平台配置

crossPlatform: InAppWebViewOptions(

useShouldOverrideUrlLoading: true,

mediaPlaybackRequiresUserGesture: false,

),

// android平台配置

android: AndroidInAppWebViewOptions(

//支持HybridComposition

useHybridComposition: true,

),

// ios平台配置

ios: IOSInAppWebViewOptions(

allowsInlineMediaPlayback: true,

),

);

@override

Widget build(BuildContext context) {

return Container(

child: InAppWebView(

key: webViewKey,

initialFile: 'lib/assets/html/demo.html',

// initialUrlRequest: URLRequest(url: Uri.parse("https://inappwebview.dev/")),

initialOptions: options,

// InAppWebview中获取InAppWebViewController

onWebViewCreated: (InAppWebViewController controller) {

webViewController = controller;

// 注册一个JS处理方法,名称为myHandlerName

controller.addJavaScriptHandler(

handlerName: 'myHandlerName',

callback: (args) {

// 打印js方传递过来的参数

print('args=js方传递过来的参数============================$args');

// 传给js方的参数

return "flutter给js的数据";

});

},

onConsoleMessage: (controller, consoleMessage) {

//这里是打印来自于js的conse.log打印

print("consoleMessage==来自于js的打印====$consoleMessage");

},

onPageCommitVisible: (inAppWebViewControlle, uri) async {

if (_loadPage) {

setState(() {

_loadPage = false;

});

var fileHtmlContents = await webViewController!.getHtml();

fileHtmlContents = fileHtmlContents!.replaceAll(

'

',

"

12345678910
",

);

webViewController!.loadData(data: fileHtmlContents);

}

},

),

);

}

}

html代码

demo

我是一个demo

我是一个html文件

我想展示在flutter应用里

5.常见问题

下载完插件直接运行会报错,需要根据报错提示修改配置;

1)在项目文件-->android-->app-->build.gradle中,变量值固定数值参考报错信息,建议为大于等于报错提示信息中的数值。

android {

compileSdkVersion 31

defaultConfig {

minSdkVersion 23

targetSdkVersion 28

}

}

好文推荐

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: