Javascript 颤振双向通信js到dart以及从dart到js的回调结果

Javascript 颤振双向通信js到dart以及从dart到js的回调结果,javascript,flutter,dart,callback,flutter-web,Javascript,Flutter,Dart,Callback,Flutter Web,我是个新手。我已经开发了js,使用webview_颤振来实现颤振飞镖通信。像这样: Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text('Plugin example'), actions: <Widget>[ MenuList(_co

我是个新手。我已经开发了js,使用webview_颤振来实现颤振飞镖通信。像这样:

Widget build(BuildContext context) {
   return MaterialApp(
      home: Scaffold(
      appBar: AppBar(
         title: const Text('Plugin example'),
         actions: <Widget>[
            MenuList(_controller.future),
         ],
      ),
      body: Builder(builder: (BuildContext context) {
         return WebView(
           initialUrl: localServerUrl,
           javascriptMode: JavascriptMode.unrestricted,
           onWebViewCreated: (WebViewController webViewController) {
             _controller.complete(webViewController);
           },
           javascriptChannels: <JavascriptChannel>[
             _scanBarcode(context),
           ].toSet(),
           onPageFinished: (String url) {
             //TODO : events after page loading finished
           },
        );
     }),
   ),
 );
}

JavascriptChannel _scanBarcode(BuildContext context) {
  return JavascriptChannel(
     name: 'Barcode',
     onMessageReceived: (JavascriptMessage message) {
       String result = scanBarcode(context);
       ******I got result of scanned barcode in result variable******
     });
}
我已在javascript通道\u Dart文件中的scanBarcode中成功获得扫描条形码的结果

现在我想在scanBarcode函数中将这个条形码结果回调到JS文件

我已经研究了这么多时间,但什么都没有得到


我被困在这里了。有人能帮我吗??提前非常感谢。

您可以使用
webViewctrl.evaluateJavascript

您可以参考
代码片段

onPressed: () {
          webViewctrl.evaluateJavascript(
              "scanBarcode('123')");
        }
我添加
console.log(消息)
到javascript函数scanBarcode以证明其工作

function scanBarcode(message) {
   console.log(message);
   if (window.Barcode && window.Barcode.postMessage) {
      console.log(document.documentElement.innerHTML);
      Barcode.postMessage(message);
   }
}
输出

I/chromium( 5209): [INFO:CONSOLE(2)] "123", source: http://yoursite/jschannel/script.js (2)
完整测试代码

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'dart:async';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

WebViewController webViewctrl;

class _MyHomePageState extends State<MyHomePage> {
  final Completer<WebViewController> _controller =
      Completer<WebViewController>();

  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: const Text('Plugin example'),
            actions: <Widget>[
              //MenuList(_controller.future),
            ],
          ),
          body: Builder(builder: (BuildContext context) {
            return WebView(
              initialUrl: 'http://yoursite/jschannel/index.html',
              javascriptMode: JavascriptMode.unrestricted,
              onWebViewCreated: (WebViewController webViewController) {
                _controller.complete(webViewController);
                webViewctrl = webViewController;
              },
              javascriptChannels: <JavascriptChannel>[
                _scanBarcode(context),
              ].toSet(),
              onPageFinished: (String url) {
                //TODO : events after page loading finished
              },
            );
          }),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              webViewctrl.evaluateJavascript(
                  "scanBarcode('123')");
            },
            child: Icon(Icons.navigation),
            backgroundColor: Colors.green,
          )),
    );
  }
}

JavascriptChannel _scanBarcode(BuildContext context) {
  return JavascriptChannel(
      name: 'Barcode',
      onMessageReceived: (JavascriptMessage message) {
        /*String result = scanBarcode(context);
        ******I got result of scanned barcode in result variable*******/
      });
}
导入“包装:颤振/材料.省道”;
导入“package:webview_flatter/webview_flatter.dart”;
导入“dart:async”;
void main()=>runApp(MyApp());
类MyApp扩展了无状态小部件{
//此小部件是应用程序的根。
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振演示”,
主题:主题数据(
主样本:颜色。蓝色,
),
主页:MyHomePage(标题:“颤振演示主页”),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>\u MyHomePageState();
}
WebViewController webViewctrl;
类_MyHomePageState扩展状态{
最终完成器控制器=
完成符();
int _计数器=0;
void _incrementCounter(){
设置状态(){
_计数器++;
});
}
@凌驾
小部件构建(构建上下文){
返回材料PP(
家:脚手架(
appBar:appBar(
标题:常量文本(“插件示例”),
行动:[
//菜单列表(_controller.future),
],
),
主体:生成器(生成器:(BuildContext上下文){
返回WebView(
初始URL:'http://yoursite/jschannel/index.html',
javascriptMode:javascriptMode.unrestricted,
onWebViewCreated:(WebViewController WebViewController){
_控制器。完成(webViewController);
webViewctrl=webViewController;
},
JavaScriptChannel:[
_扫描条形码(上下文),
].toSet(),
onPageFinished:(字符串url){
//TODO:页面加载完成后的事件
},
);
}),
浮动操作按钮:浮动操作按钮(
已按下:(){
webViewctrl.evaluateJavascript(
“扫描条码('123')”;
},
子:图标(Icons.navigation),
背景颜色:Colors.green,
)),
);
}
}
JavascriptChannel\u scanBarcode(构建上下文){
返回JavascriptChannel(
名称:'条形码',
onMessageReceived:(JavascriptMessage消息){
/*字符串结果=扫描条形码(上下文);
******我在结果变量中得到了扫描条形码的结果*******/
});
}

谢谢您的回答。。它起作用了。我们不能直接返回dart文件中的结果,比如
返回结果
,然后使用premise then()进入JavaScript函数吗。。像这样的事<代码>扫描条形码(..)。然后(函数(barcodeResult){//result from Dart})很乐意提供帮助。如果有帮助,请将此标记为答案,谢谢。您可以进行字符串连接,让javascript执行/计算此字符串。在此之前,您必须确保这个长字符串有效。@chunhunghan您好,谢谢您的回答,我想问一下JavascriptChannel参数名称上的
条形码是什么意思?是js文件的类名吗?如果我调用
window.postMessage(result),我还能得到结果吗在javascript函数上?
I/chromium( 5209): [INFO:CONSOLE(2)] "123", source: http://yoursite/jschannel/script.js (2)
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'dart:async';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

WebViewController webViewctrl;

class _MyHomePageState extends State<MyHomePage> {
  final Completer<WebViewController> _controller =
      Completer<WebViewController>();

  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: const Text('Plugin example'),
            actions: <Widget>[
              //MenuList(_controller.future),
            ],
          ),
          body: Builder(builder: (BuildContext context) {
            return WebView(
              initialUrl: 'http://yoursite/jschannel/index.html',
              javascriptMode: JavascriptMode.unrestricted,
              onWebViewCreated: (WebViewController webViewController) {
                _controller.complete(webViewController);
                webViewctrl = webViewController;
              },
              javascriptChannels: <JavascriptChannel>[
                _scanBarcode(context),
              ].toSet(),
              onPageFinished: (String url) {
                //TODO : events after page loading finished
              },
            );
          }),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              webViewctrl.evaluateJavascript(
                  "scanBarcode('123')");
            },
            child: Icon(Icons.navigation),
            backgroundColor: Colors.green,
          )),
    );
  }
}

JavascriptChannel _scanBarcode(BuildContext context) {
  return JavascriptChannel(
      name: 'Barcode',
      onMessageReceived: (JavascriptMessage message) {
        /*String result = scanBarcode(context);
        ******I got result of scanned barcode in result variable*******/
      });
}