
Я хочу рассказать вам о том, как отправлять сообщения из Flutter WebView в JS:
1. В коде JS вам нужно привязать вашу функцию, вам нужно:
const function = () => alert('hello from JS');
window.function = function;
2. В вашем коде реализации виджета WebView вам необходимо объявить метод onWebViewCreated следующим образом:
WebView(
onWebViewCreated: (WebViewController controller) {},
initialUrl: 'https://url.com',
javascriptMode: JavascriptMode.unrestricted,
)
3. В виджете класса объявить var _webViewController;
class App extends State<MyApp> {
final _webViewController;
}
4. В 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 экземпляром с другими виджетами, такими как ящик?
В данном случае я решил реализовать 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);
},
И, наконец, в нашем виджете Drawer, т.е. (здесь вы можете использовать любой виджет, который хотите)
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');
2. В вашем коде флаттера:
Когда вы запускаете JavascriptChannel(name: ‘CHANNEL_NAME’, …)
привязку flutter к вашему окну WebView new 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',
)
Итак, мы здесь.
Так что, если у вас есть еще один лучший опыт по этому поводу, вы можете написать в комментариях, чтобы помочь другим людям!