当前位置:   article > 正文

Flutter与Webview交互_window.flutter_inappwebview.callhandler

window.flutter_inappwebview.callhandler

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中加入

  1. // 不加这个强制横/竖屏会报错
  2. WidgetsFlutterBinding.ensureInitialized();

3.主要类概览

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

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

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

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

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

  • ......

4.使用

(1)加载webview视图

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

flutter代码如下:

app上呈现的效果图:

2) 展示一个html视图内容

html代码如下:

flutter代码:

在app上呈现的效果:

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

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

那么在flutter代码中添加

  1. //在InAppWebView配置项中添加
  2. onPageCommitVisible: (inAppWebViewControlle, uri) async {
  3. //_loadPage是声明的一个全局bool类型变量
  4. if (_loadPage) {
  5. setState(() {
  6. _loadPage = false;
  7. });
  8. //获取到webview的所有html结构
  9. var fileHtmlContents = await webViewController!.getHtml();
  10. //找到带有某种唯一标识的demo结构并替换它
  11. fileHtmlContents = fileHtmlContents!.replaceAll(
  12. '<div class="flutter-view"></div>',
  13. "<div class='flutter-view' style='width: 200px; height: 200px;background-color: green;'>12345678910</div>",
  14. );
  15. //重新渲染结构
  16. webViewController!.loadData(data: fileHtmlContents);
  17. }
  18. },

效果:

(2)与js交互传参

在flutter代码中添加

  1. //添加在InAppWebView配置项里
  2. // InAppWebview中获取InAppWebViewController
  3. onWebViewCreated: (InAppWebViewController controller) {
  4. // 注册一个JS处理方法,名称为myHandlerName
  5. controller.addJavaScriptHandler(
  6. handlerName: 'myHandlerName',
  7. callback: (args) {
  8. // 打印js方传递过来的参数
  9. print('args=js方传递过来的参数============================$args');
  10. // 传给js方的参数
  11. // 可以传递你所需要的任意类型数据,数组、对象等
  12. return "flutter给js的数据";
  13. });
  14. },
  1. //这个方法可以打印js中的conse.log内容
  2. onConsoleMessage: (controller, consoleMessage) {
  3. //这里是打印来自于js的conse.log打印
  4. print("consoleMessage==来自于js的打印====$consoleMessage");
  5. },

在js代码中添加

  1. // 下面的"flutterInAppWebViewPlatformReady"为固定写法
  2. // "myHandlerName"与flutter中注册的JS处理方法名称一致
  3. window.addEventListener("flutterInAppWebViewPlatformReady", function () {
  4. window.flutter_inappwebview
  5. //可以传递你所需要的任意类型数据,数组、对象等
  6. .callHandler("myHandlerName", "这里是传给flutter的参数")
  7. .then(function (res) {
  8. console.log("res========flutter给html的数据", res);
  9. })
  10. })

flutter控制台输出:

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

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

(3)完整demo代码

flutter代码

  1. import 'package:flutter/cupertino.dart';
  2. import 'package:flutter_inappwebview/flutter_inappwebview.dart';
  3. class HomePage extends StatefulWidget {
  4. HomePage({Key? key, required this.url}) : super(key: key);
  5. String url;
  6. @override
  7. State<HomePage> createState() => _HomePageState();
  8. }
  9. class _HomePageState extends State<HomePage> {
  10. bool _loadPage = true;
  11. InAppWebViewController? webViewController;
  12. // GlobalKey可以获取到对应的Widget的State对象!
  13. // 当我们页面内容很多时,而需要改变的内容只有很少的一部分且在树的底层的时候,我们如何去实现增量更新?
  14. // 通常情况下有两种方式,第一种是通过方法的回调,去实现数据更新,第二种是通过GlobalKey,
  15. final GlobalKey webViewKey = GlobalKey();
  16. // webview配置
  17. InAppWebViewGroupOptions options = InAppWebViewGroupOptions(
  18. // 跨平台配置
  19. crossPlatform: InAppWebViewOptions(
  20. useShouldOverrideUrlLoading: true,
  21. mediaPlaybackRequiresUserGesture: false,
  22. ),
  23. // android平台配置
  24. android: AndroidInAppWebViewOptions(
  25. //支持HybridComposition
  26. useHybridComposition: true,
  27. ),
  28. // ios平台配置
  29. ios: IOSInAppWebViewOptions(
  30. allowsInlineMediaPlayback: true,
  31. ),
  32. );
  33. @override
  34. Widget build(BuildContext context) {
  35. return Container(
  36. child: InAppWebView(
  37. key: webViewKey,
  38. initialFile: 'lib/assets/html/demo.html',
  39. // initialUrlRequest: URLRequest(url: Uri.parse("https://inappwebview.dev/")),
  40. initialOptions: options,
  41. // InAppWebview中获取InAppWebViewController
  42. onWebViewCreated: (InAppWebViewController controller) {
  43. webViewController = controller;
  44. // 注册一个JS处理方法,名称为myHandlerName
  45. controller.addJavaScriptHandler(
  46. handlerName: 'myHandlerName',
  47. callback: (args) {
  48. // 打印js方传递过来的参数
  49. print('args=js方传递过来的参数============================$args');
  50. // 传给js方的参数
  51. return "flutter给js的数据";
  52. });
  53. },
  54. onConsoleMessage: (controller, consoleMessage) {
  55. //这里是打印来自于js的conse.log打印
  56. print("consoleMessage==来自于js的打印====$consoleMessage");
  57. },
  58. onPageCommitVisible: (inAppWebViewControlle, uri) async {
  59. if (_loadPage) {
  60. setState(() {
  61. _loadPage = false;
  62. });
  63. var fileHtmlContents = await webViewController!.getHtml();
  64. fileHtmlContents = fileHtmlContents!.replaceAll(
  65. '<div class="flutter-view"></div>',
  66. "<div class='flutter-view' style='width: 200px; height: 200px;background-color: green;'>12345678910</div>",
  67. );
  68. webViewController!.loadData(data: fileHtmlContents);
  69. }
  70. },
  71. ),
  72. );
  73. }
  74. }

html代码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>demo</title>
  8. <script>
  9. // 下面的"flutterInAppWebViewPlatformReady"为固定写法
  10. // "myHandlerName"与flutter中注册的JS处理方法名称一致
  11. window.addEventListener("flutterInAppWebViewPlatformReady", function () {
  12. window.flutter_inappwebview
  13. .callHandler("myHandlerName", "这里是传给flutter的参数")
  14. .then(function (res) {
  15. console.log("res========flutter给html的数据", res);
  16. })
  17. })
  18. </script>
  19. </head>
  20. <body>
  21. <h1>我是一个demo</h1>
  22. <h1>我是一个html文件</h1>
  23. <h1>我想展示在flutter应用里</h1>
  24. <div class="flutter-view"></div>
  25. </body>
  26. </html>

5.常见问题

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

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

  1. android {
  2. compileSdkVersion 31
  3. defaultConfig {
  4. minSdkVersion 23
  5. targetSdkVersion 28
  6. }
  7. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/93521
推荐阅读
相关标签
  

闽ICP备14008679号