当前位置:首页 » 《我的小黑屋》 » 正文

flutter开发实战-inappwebview实现flutter与Javascript方法调用

8 人参与  2024年04月01日 13:25  分类 : 《我的小黑屋》  评论

点击全文阅读


flutter开发实战-inappwebview实现flutter与Javascript方法调用

在使用inappwebview时候,需要flutter端与JS进行交互,调用相应的方法,在inappwebview中的JavaScript Handlers。
在这里插入图片描述

一、JavaScript Handlers

要添加JavaScript Handlers,可以使用InAppWebViewController.addJavaScriptHandler方法,在该方法中定义handlerName和JavaScript端调用它时要调用的回调。回调可以返回要在JavaScript端发送的数据。如果您需要在加载网页后立即管理JavaScript处理程序,则应在创建InAppWebView时调用InAppWebViewController.addJavaScriptHandler。

以下是如何注册JavaScript处理程序的示例:

onWebViewCreated: (controller) {  // register a JavaScript handler with name "myHandlerName"  controller.addJavaScriptHandler(handlerName: 'myHandlerName', callback: (args) {    // print arguments coming from the JavaScript side!    print(args);    // return data to the JavaScript side!    return {      'bar': 'bar_value', 'baz': 'baz_value'    };  });},

在JavaScript端,要执行回调处理程序并将数据发送到Flutter,您需要使用window.Flutter_inappwebview.callHandler(handlerName,…args)方法,其中handlerName是一个字符串,表示您正在调用的处理程序名称,args是可以发送到Fluter方面的可选参数。

注意:

如果相更换一个名字,我们可以更换一个名字来嵌套window.flutter_inappwebview

window.myCustomObj = { callHandler: window.flutter_inappwebview.callHandler } and, then, you can use window.myCustomObj.callHandler

此外,可以通过这种方式包装整个特定的处理代码:

const myHandlerName = (…args) => window.flutter_inappwebview.callHandler(‘myHandlerName’, …args);

然后调用myHandlerName();

在Javascript端,如果需要调用callHandler,需要监听flatterInAppWebViewPlatformReady。可以使用在flatterInAppWebViewPlatformReady事件被分派时设置的全局标志变量,并在调用window.flutter_inappwebview.callHandler方法之前使用它。

示例代码如下

// execute inside the "flutterInAppWebViewPlatformReady" event listenerwindow.addEventListener("flutterInAppWebViewPlatformReady", function(event) { const args = [1, true, ['bar', 5], {foo: 'baz'}]; window.flutter_inappwebview.callHandler('myHandlerName', ...args);});// or using a global flag variablevar isFlutterInAppWebViewReady = false;window.addEventListener("flutterInAppWebViewPlatformReady", function(event) { isFlutterInAppWebViewReady = true;});// then, somewhere in your codeif (isFlutterInAppWebViewReady) { const args = [1, true, ['bar', 5], {foo: 'baz'}]; window.flutter_inappwebview.callHandler('myHandlerName', ...args);}

在flutter端,Flutter在执行注入方法时候,调用evaluateJavascript来执行callHandler,这个flutterInAppWebViewPlatformReady无需监听,因为这个flutterInAppWebViewPlatformReady已经Ready了。

可以在onLoadStop中调用代码

onLoadStop: (controller, url) async {  await controller.evaluateJavascript(source: """    const args = [1, true, ['bar', 5], {foo: 'baz'}];    window.flutter_inappwebview.callHandler('myHandlerName', ...args);  """);},

window.flutter_inappwebview.callHandler返回一个JavaScript Promise,该Promise可用于获取回调返回的json结果。在这种情况下,只需返回您想要发送的数据,它将使用dart:convert库中的jsonEncode自动进行json编码。

一个简单的示例代码

import 'dart:async';import 'dart:io';import 'package:flutter/material.dart';import 'package:flutter_inappwebview/flutter_inappwebview.dart';Future main() async {  WidgetsFlutterBinding.ensureInitialized();  if (Platform.isAndroid) {    await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);  }    runApp(new MyApp());}class MyApp extends StatefulWidget {  @override  _MyAppState createState() => new _MyAppState();}class _MyAppState extends State<MyApp> {  InAppWebViewGroupOptions options = InAppWebViewGroupOptions(      android: AndroidInAppWebViewOptions(        useHybridComposition: true,      ),);  @override  Widget build(BuildContext context) {    return MaterialApp(      home: Scaffold(          appBar: AppBar(title: Text("JavaScript Handlers")),          body: SafeArea(              child: Column(children: <Widget>[                Expanded(                  child: InAppWebView(                    initialData: InAppWebViewInitialData(                        data: """<!DOCTYPE html><html lang="en">    <head>        <meta charset="UTF-8">        <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">    </head>    <body>        <h1>JavaScript Handlers</h1>        <script>            window.addEventListener("flutterInAppWebViewPlatformReady", function(event) {                window.flutter_inappwebview.callHandler('handlerFoo')                  .then(function(result) {                    // print to the console the data coming                    // from the Flutter side.                    console.log(JSON.stringify(result));                                        window.flutter_inappwebview                      .callHandler('handlerFooWithArgs', 1, true, ['bar', 5], {foo: 'baz'}, result);                });            });        </script>    </body></html>                      """                    ),                    initialOptions: options,                    onWebViewCreated: (controller) {                      controller.addJavaScriptHandler(handlerName: 'handlerFoo', callback: (args) {                        // return data to the JavaScript side!                        return {                          'bar': 'bar_value', 'baz': 'baz_value'                        };                      });                      controller.addJavaScriptHandler(handlerName: 'handlerFooWithArgs', callback: (args) {                        print(args);                        // it will print: [1, true, [bar, 5], {foo: baz}, {bar: bar_value, baz: baz_value}]                      });                    },                    onConsoleMessage: (controller, consoleMessage) {                      print(consoleMessage);                      // it will print: {message: {"bar":"bar_value","baz":"baz_value"}, messageLevel: 1}                    },                  ),                ),              ]))),    );  }}

二、监听自定义CustomEvent

可以设置一个消息事件侦听器(与postMessage一起使用)或一个自定义事件侦听器。

// message event listenerwindow.addEventListener("message", (event) => {  console.log(event.data);}, false);// or custom event listenerwindow.addEventListener("myCustomEvent", (event) => {  console.log(event.detail);}, false);

然后使用window.dispatch

// using postMessage methodwindow.postMessage({foo: 1, bar: false});// or dispatching a custom eventconst event = new CustomEvent("myCustomEvent", {    detail: {foo: 1, bar: false}});window.dispatchEvent(event);

因此,可以在运行时使用InAppWebViewController.eevaluatteJavascript方法或在web应用程序内部设置这些事件侦听器,并使用相同的方法调度这些事件。

例如:

onLoadStop: (controller, url) async {  await controller.evaluateJavascript(source: """    window.addEventListener("myCustomEvent", (event) => {      console.log(JSON.stringify(event.detail));    }, false);  """);  await Future.delayed(Duration(seconds: 5));  controller.evaluateJavascript(source: """    const event = new CustomEvent("myCustomEvent", {      detail: {foo: 1, bar: false}    });    window.dispatchEvent(event);  """);},onConsoleMessage: (controller, consoleMessage) {  print(consoleMessage);  // it will print: {message: {"foo":1,"bar":false}, messageLevel: 1}},

三、小结

flutter开发实战-inappwebview实现flutter与Javascript方法调用。描述可能不是特别准确,请见谅。

学习记录,每天不停进步。


点击全文阅读


本文链接:http://zhangshiyu.com/post/88948.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1