Я хочу рассказать вам о том, как отправлять сообщения из 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', )
Итак, мы здесь.
Так что, если у вас есть еще один лучший опыт по этому поводу, вы можете написать в комментариях, чтобы помочь другим людям!