Flutter two way communication js to dart and callback result from dart to js
4,594
You can use webViewctrl.evaluateJavascript
you can reference https://www.elasticfeed.com/7ee71117c626c2021eb919c182ec483a/
code snippet
onPressed: () {
webViewctrl.evaluateJavascript(
"scanBarcode('123')");
}
I add console.log(message);
to javascript function scanBarcode to prove it work
function scanBarcode(message) {
console.log(message);
if (window.Barcode && window.Barcode.postMessage) {
console.log(document.documentElement.innerHTML);
Barcode.postMessage(message);
}
}
Output
I/chromium( 5209): [INFO:CONSOLE(2)] "123", source: http://yoursite/jschannel/script.js (2)
full test code
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*******/
});
}
Author by
Ankit Sathvara
Updated on December 16, 2022Comments
-
Ankit Sathvara over 1 year
I am new to flutter. I have developed js to flutter dart communication using webview_flutter. like this :
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****** }); }
server html file
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="script.js"></script> </head> <body> <button id="btnBarcode" style="margin-top:20px; height:30px;">Scan Barcode</button> </body> </html>
and this is JS file
function scanBarcode(message) { if (window.Barcode && window.Barcode.postMessage) { Barcode.postMessage(message); } } window.onload = function () { document.getElementById('btnBarcode').onclick = function () { scanBarcode("Scan Barcode"); } }
I have successfully got result of scanned barcode in javascript channel _scanBarcode in Dart file.
Now I want to callback this barcode result back to JS file in scanBarcode function.
I have researched so much time but not getting anything.
I am stuck here. Can anyone help me?? Thank you so much in advance.
-
Ankit Sathvara over 4 yearsThank you for your answer.. Its working. Can't we do directly return result like
return result
in dart file, and that we will get in JavaScript function using premise then().. somthing like this..scanBarcode(..).then(function (barcodeResult) {// result from Dart})
-
chunhunghan over 4 yearsGlad to help. please mark this as answer if it help, thanks.
-
chunhunghan over 4 yearsyou can do string concatenation to let javascript execute/evaluate this string. before that you have to make sure this long string works.
-
MNFS almost 4 years@chunhunghan hi thanks for the answer, i want to ask what is the
Barcode
means on JavascriptChannel param name? is it class name of js file? can i still got result if i callwindow.postMessage(result);
on the javascript func?