当前位置:   article > 正文

Flutter项目中添加Webview(八)使用JavaScript渠道_flutter addjavascriptchannel

flutter addjavascriptchannel

借助JavascriptChannel,您的应用可以在WebView的JavaScript上下文中注册回调处理程序,可以调用这些回调处理程序将值传递回应用的Dart代码。在此步骤中,您将注册一个使用 SMLHttpRequest的结果调用SnackBar

将WebViewStack类更新如下所示:

class WebViewStack extends StatefulWidget {const WebViewStack({required this.controller, Key? key}) : super(key: key);final Completer<WebViewController> controller;@overrideState<WebViewStack> createState() => _WebViewStackState();
}

class _WebViewStackState extends State<WebViewStack> {var loadingPercentage = 0;@overrideWidget build(BuildContext context) {return Stack(children: [WebView(initialUrl: 'https://flutter.dev',onWebViewCreated: (webViewController) {widget.controller.complete(webViewController);},onPageStarted: (url) {setState(() {loadingPercentage = 0;});},onProgress: (progress) {setState(() {loadingPercentage = progress;});},onPageFinished: (url) {setState(() {loadingPercentage = 100;});},navigationDelegate: (navigation) {final host = Uri.parse(navigation.url).host;if (host.contains('youtube.com')) {ScaffoldMessenget.of(context).showSnackBar(SnackBar(content: Text('Bloacking navigation to @host',),),);return NavigationDecision.prevent;}return NavigationDecision.navigate;},javascriptMode: JavasctiptMode.unrestricted,javascriptChannels: _createJavascriptChannels(context), // Add this line);),if (loadingPercentage < 100) LinearProgressIndicator(value: loadingPercentage / 100.0,),]}// Add from here...Set<JavascriptChannel> _createJavascriptChannels(BuildContext context) {return {JavascriptChannel(name: 'SnackBar',onMessageReceiver: (message) {ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(message.message));}),};}// ... to here
} 
  • 1
  • 2
  • 3
  • 4
  • 5

对于Set中的每个JavascriptChannel,渠道对象会在JavaScript上下文中以JavascriptChannel.name同名的窗口属性的形式提供。如需在JavaScript上下文中使用此渠道,则需要在JavascriptChannel上调用postMessage,以发送一条消息,该消息会传递到已命名的JavascriptChannelonMessageReceived回调处理程序。

如需使用上下文添加的JavascriptChannel,请再添加一个菜单项。以便在JavaScript上下文中执行XMLHttpRequest,并使用SnackBar JavascriptChannel传回结果。

现在,WebView已了解JavascroptChannels。接下来将添加一个示例进一步扩展该应用。

enum _MenuOptions {navagationDelegate,userAgent,javascriptChannel, // Add this line
}

class Menu extends StatelessWidget {const Menu({required this.controller, Key? key}) : super(key: key);final Completer<WebViewController> controller;@overrideWidget build(BuildContext context) {return FutureBuilder<WebViewControoller>(future: controller.future,builder: (context, controller) { return PopupMenuButton<_MenuOptions>( onSelected: (value) async { switch(value) { case _MenuOptions.navigationDelegate: controller.data<img src="https://youtube.com'); break; case _MenuOptions.userAgent: final userAgent = await controller.data!.runJavascriptReturningResult('navigator.userAgent'); ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(userAgent))); break; // Add from here .. case _MenuOptions.javascriptChannel: await controller.data!..runJavascript(''' var req = new XMLHtppRequesst(); req.open('GET', "https://api.ipify.org/?format=json"); req.onload = function() { if (req.status == 200) { let reqponse = JSON.parse(req.responseText); SnackBar.postMessage("IP Address : " + response.ip); } else { SnackBar.posttMessage:("Error: " + req.status);  } } req.send(); '''); // ... to here } }, itemBuilder: (context) => [ cosnt PopupMenuItem<_MenuOptions>( value: _MenuOptions.navigationDelegate, child: Text(Navigate to Youtybe), ), const PopupMenuItem<_MenuOptions>( value: _MenuOptions.userAgent, child: Text('Show user-agent'), ), // Add from here ... const PopupMenuItem<_MenuOptions>( value: _MenuOptions.javascriptChannel, child: Text('Loopup IP Address'), ), //...to here. ] );});" style="margin: auto" />
} 
  • 1
  • 2
  • 3
  • 4
  • 5

当用弧线则JavaScript Channel Example菜单选项时,系统会执行此JavaScriipt。

var req = new XMLHttpRequest();
req.open('GET', "http://api.ipify.org/?format=json");
req.onload = function() {if (req.status == 200_ {SnackBar.postMessage(req.responseText);} else {SnackBar.poostMessage("Error: " + req.status);}
}
req.send(); 
  • 1
  • 2
  • 3
  • 4
  • 5

此代码会向公共IP地址API发送GET请求,并返回设备的IP地址。对SnackBar JavascriptChannel调用postMessage,系统会在SnackBar中显示结果。

最后

整理了75个JS高频面试题,并给出了答案和解析,基本上可以保证你能应付面试官关于JS的提问。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/106006?site
推荐阅读
相关标签
  

闽ICP备14008679号