我有一个html文件,我正在使用flutter_webview_plugin在Flutter webview中加载它。我正在使用evalJavascript来调用javascript代码中的函数,即flutter(dart)->js。然而,我也需要一些方法来将一些东西传回flutter(dart)层,即js->flutter(dart)。
我已经尝试使用- webkit.messageHandlers.native - window.native来支持这两个平台(Android,iOS),检查它们在JS中是否可用。但是,这些都是未定义的。使用以下代码在JS中获取本机处理程序的实例。
typeof webkit !== 'undefined' ? webkit.messageHandlers.native :
window.native;
即使我使用它获取实例并发布消息,也不确定如何在flutter(dart)层中处理它。我可能需要使用平台通道。我不确定我是否走对了方向。
有什么方法可以让我做到这一点吗?我已经评估了interactive_webview插件。它在Android上运行得很好。但是,它有迅速的版本问题,不想继续下去。
任何帮助都将不胜感激。
发布于 2019-03-12 13:54:22
这是一个从Javascript代码到flutter的通信示例。
在Flutter中构建WebView,如下所示:
WebView(
initialUrl: url,
javascriptMode: JavascriptMode.unrestricted,
javascriptChannels: Set.from([
JavascriptChannel(
name: 'Print',
onMessageReceived: (JavascriptMessage message) {
//This is where you receive message from
//javascript code and handle in Flutter/Dart
//like here, the message is just being printed
//in Run/LogCat window of android studio
print(message.message);
})
]),
onWebViewCreated: (WebViewController w) {
webViewController = w;
},
)
在你的HTMLfile中:
<script type='text/javascript'>
Print.postMessage('Hello World being called from Javascript code');
</script>
当您运行这段代码时,您应该能够在android studio的LogCat/Run窗口中看到日志"Hello World in from Javascript code“。
发布于 2019-11-28 05:18:54
您可以尝试我的插件编辑( flutter_inappbrowser :它已重命名为flutter_inappwebview),并使用addJavaScriptHandler({@required String handlerName, @required JavaScriptHandlerCallback callback})
方法(请参阅更多here)。
下面给出了一个示例。在颤动方面:
...
child: InAppWebView(
initialFile: "assets/index.html",
initialHeaders: {},
initialOptions: InAppWebViewWidgetOptions(
inAppWebViewOptions: InAppWebViewOptions(
debuggingEnabled: true,
)
),
onWebViewCreated: (InAppWebViewController controller) {
webView = controller;
controller.addJavaScriptHandler(handlerName: "mySum", callback: (args) {
// Here you receive all the arguments from the JavaScript side
// that is a List<dynamic>
print("From the JavaScript side:");
print(args);
return args.reduce((curr, next) => curr + next);
});
},
onLoadStart: (InAppWebViewController controller, String url) {
},
onLoadStop: (InAppWebViewController controller, String url) {
},
onConsoleMessage: (InAppWebViewController controller, ConsoleMessage consoleMessage) {
print("console message: ${consoleMessage.message}");
},
),
...
在assets端(例如,JavaScript文件夹中的本地文件assets/index.html
):
<!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">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Flutter InAppBrowser</title>
...
</head>
<body>
...
<script>
// In order to call window.flutter_inappwebview.callHandler(handlerName <String>, ...args)
// properly, you need to wait and listen the JavaScript event flutterInAppWebViewPlatformReady.
// This event will be dispatched as soon as the platform (Android or iOS) is ready to handle the callHandler method.
window.addEventListener("flutterInAppWebViewPlatformReady", function(event) {
// call flutter handler with name 'mySum' and pass one or more arguments
window.flutter_inappwebview.callHandler('mySum', 12, 2, 50).then(function(result) {
// get result from Flutter side. It will be the number 64.
console.log(result);
});
});
</script>
</body>
</html>
在Android Studio日志中,您将获得:
I/flutter (20436): From JavaScript side:
I/flutter (20436): [12, 2, 50]
I/flutter (20436): console message: 64
发布于 2020-10-17 22:48:59
我想告诉你如何从flutter WebView向JS发送消息:
的函数
const function = () => alert('hello from JS');
window.function = function;
在WebView小部件实现的代码中,需要像下面这样声明
WebView(
onWebViewCreated: (WebViewController controller) {},
initialUrl: 'https://url.com',
javascriptMode: JavascriptMode.unrestricted,
)
类小部件声明var _webViewController;
中的
class App extends State<MyApp> {
final _webViewController;
}
onWebViewCreated中的
onWebViewCreated: (WebViewController controller) {
_webViewController = controller;
},
然后,您可以像这样运行代码:
class App extends StatelessWidget {
var _webViewController;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
body: WebView(
onWebViewCreated: (WebViewController controller) {
_webViewController = controller;
},
initialUrl: 'https://url.com',
javascriptMode: JavascriptMode.unrestricted,
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// When you click at this button youll run js code and youll see alert
_webViewController
.evaluateJavascript('window.function ()');
},
child: Icon(Icons.add),
backgroundColor: Colors.green,
),
),
);
}
}
但是,如果我们想把这个_webViewController
实例分享给像drawer这样的小部件,该怎么办呢?
在本例中,我决定实现Singleton pattern
并将_webViewController
实例存储在其中。
所以
单例类
class Singleton {
WebViewController webViewController;
static final Singleton _singleton = new Singleton._internal();
static Singleton get instance => _singleton;
factory Singleton(WebViewController webViewController) {
_singleton.webViewController = webViewController;
return _singleton;
}
Singleton._internal();
}
然后
onWebViewCreated: (WebViewController controller) {
var singleton = new Singleton(controller);
},
最后,在我们的抽屉小部件中(在这里你可以使用任何你想要的小部件)
class EndDrawer extends StatelessWidget {
final singleton = Singleton.instance;
@override
Widget build(BuildContext context) {
return Drawer(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
SizedBox(
width: 200,
child: FlatButton(
onPressed: () {
singleton.webViewController.evaluateJavascript('window.function()');
Navigator.pop(context); // exit drawer
},
child: Row(
children: <Widget>[
Icon(
Icons.exit_to_app,
color: Colors.redAccent,
),
SizedBox(
width: 30,
),
Text(
'Exit',
style: TextStyle(color: Colors.blueAccent, fontSize: 20),
),
],
),
)),
],
),
);
}
}
如果你想从JS代码接收消息到你的flutter应用,你需要:
在您的js代码中使用
window.CHANNEL_NAME.postMessage('Hello from JS');
你的flutter代码中的
当您运行JavascriptChannel(名称:'CHANNEL_NAME',...)
flutter绑定到你的窗口,用你在构造函数中写的名字WebView新的MessageChannel (在这个例子中是CHANNEL_NAME
)
因此,当我们呼叫window.CHANNEL_NAME.postMessage('Hello from JS');
时,会收到一条我们发送给的消息
WebView(
javascriptChannels: [
JavascriptChannel(name: 'CHANNEL_NAME', onMessageReceived: (message) {
print(message.message);
})
].toSet(),
initialUrl: 'https://url.com',
)
所以我们到了这里。
我是flutter代码的新手
因此,如果你对此有更好的体验,你可以写评论来帮助其他人!
https://stackoverflow.com/questions/53689662
复制相似问题