博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Flutter UI基础 - webview 使用和交互
阅读量:4049 次
发布时间:2019-05-25

本文共 4649 字,大约阅读时间需要 15 分钟。

在Flutter中使用webview,在中查看,有几个组件都可以使用webview

 

本文使用的是,它是Flutter团队开发的,目前还不是正式版,但已经可以使用。在iOS中底层调用的是WKWebView,在Android中底层调用的是WebView

webview_flutter 使用

  1. 添加组件 
  2. 主要代码
  3. 针对iOS,需要在ios-Runner-info.plist中添加
WebView(   initialUrl: "https://flutterchina.club/",   //JS执行模式 是否允许JS执行   javascriptMode: JavascriptMode.unrestricted, )
io.flutter.embedded_views_preview
YES

第三步不可少,否则会报错。

 

Flutter调用JS

在调用之前 先看一下WebView的其他参数:

WebView创建完成时调用

onWebViewCreated,

要显示的url

initialUrl

JS执行模式 默认是不调用

javascriptMode = JavascriptMode.disabled

使用javascriptChannel JS可以调用Flutter

javascriptChannels

拦截请求

navigationDelegate

手势

gestureRecognizers

页面加载完成

onPageFinished

通过WebViewController调用evaluateJavascript方法,即可调用JS。

了解了每个参数的作用之后,交互就看似简单了。

Flutter调用JS的流程:

  1. WebView创建完成时在onWebViewCreated 中,获取到WebViewController实例。
  2. 当页面加载完成之后,即onPageFinished之后,通过WebViewControllerevaluateJavascript方法调用JS。
  3. evaluateJavascript返回的是Future<String>,通过Future可以获取到JS的返回结果。

示例代码: 在页面加载完成之后,获取网页标题,并显示在导航栏上。

WebView(    initialUrl: "https://flutterchina.club/",    //JS执行模式 是否允许JS执行    javascriptMode: JavascriptMode.unrestricted,    onWebViewCreated: (controller) {      _controller = controller;    },    onPageFinished: (url) {        _controller.evaluateJavascript("document.title").then((result){          setState(() {            _title = result;          });        }      );    },  )

效果:

 

JS调用Flutter

JS调用Flutter主要看剩下的两个参数:

javascriptChannels

navigationDelegate

这两个参数都可以从JS调用Flutter,可以单独使用,也可以混合使用。

javascriptChannels使用:

javascriptChannels类似于往JS中注册方法,这些方法名要和web端约定好。

javascriptChannels参数接受Set<JavascriptChannel>一个成员类型为JavascriptChannel的Set集合。

来看一下JavascriptChannel的用法:

JavascriptChannel(  name: "share",  onMessageReceived: (JavascriptMessage message)    {        print("参数为: ${message.message}");  })

在JS端就可以调用share方法,同时可以传递参数,在Flutter中通过JavascriptMessage可以获取到参数。

navigationDelegate使用:

navigationDelegate: (NavigationRequest request) {  //对于需要拦截的操作 做判断  if(request.url.startsWith("myapp://")) {    print("即将打开 ${request.url}");    //做拦截处理    //pushto....         Application.push(context, request.url);    return NavigationDecision.prevent;  }    //不需要拦截的操作  return NavigationDecision.navigate;} ,

例如想要通过webview打开app的原生页面,通过约定好的链接,拦截到指定链接后可跳转到原生页面。

完整示例代码:

import 'package:flutter/cupertino.dart';import 'package:webview_flutter/webview_flutter.dart';class WebViewPage extends StatefulWidget {  @override  _WebViewPageState createState() => _WebViewPageState();}class _WebViewPageState extends State
{ WebViewController _controller; String _title = "webview"; @override Widget build(BuildContext context) { return CupertinoPageScaffold( navigationBar: CupertinoNavigationBar( middle: Text("$_title"), ), child: SafeArea( child: WebView( initialUrl: "https://flutterchina.club/", //JS执行模式 是否允许JS执行 javascriptMode: JavascriptMode.unrestricted, onWebViewCreated: (controller) { _controller = controller; }, onPageFinished: (url) { _controller.evaluateJavascript("document.title").then((result){ setState(() { _title = result; }); } ); }, navigationDelegate: (NavigationRequest request) { if(request.url.startsWith("myapp://")) { print("即将打开 ${request.url}"); return NavigationDecision.prevent; } return NavigationDecision.navigate; } , javascriptChannels:
[ JavascriptChannel( name: "share", onMessageReceived: (JavascriptMessage message) { print("参数: ${message.message}"); } ), ].toSet(), ), ), ); }}

可能已经有同学看出来了,JS调用Flutter时,JS获取不到Flutter的返回值,目前还没有找到直接的解决办法,但可以通过迂回的方法解决。

下面提供两种思路:

  1. js调用Flutter时,除了传递业务需要的参数之外,再添加一个callbackname参数
    通过callbackname参数把JS调用Flutter和Flutter返回参数绑定起来。
JavascriptChannel(       name: "share",       onMessageReceived: (JavascriptMessage message) {       print("参数: ${message.message}");                        String callbackname = message.message; //实际应用中要通过map通过key获取                          String data = "收到消息调用了";        String script = "$callbackname($data)";         _controller.evaluateJavascript(script);       }  )

2.在网页加载成功后,把JS需要获取的Flutter的值,注入到widow上, 在JS中就可以通过widow获取到相应的值。

String script = "window.isLogin=是否登录"; _controller.evaluateJavascript(script).then((result){   });

作者:王大妈啊
链接:https://www.jianshu.com/p/4aabe453eb26
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

你可能感兴趣的文章
fhs-framework jetcache 缓存维护之自动清除缓存
查看>>
SpringBoot 动态编译 JAVA class 解决 jar in jar 的依赖问题
查看>>
fhs_framework springcloud使用统一的控制器来接收rpc调用请求教程,无需每个rpc接口都写控制器
查看>>
fhs-framework springboot mybatis 解决表关联查询问题的关键方案-翻译服务
查看>>
Springboot + easyui + mybatis 高级搜索功能实现
查看>>
k8s 踩坑笔记
查看>>
SpringCloud Seata Nacos 整合教程和坑
查看>>
nacos 本地覆盖远程 本地优先
查看>>
java 查询内存泄漏
查看>>
httpclient4.5 绕过ssl证书校验 -看别人文章解决不了的,看下我这个
查看>>
基于webpack的vue语法糖实现思路
查看>>
jenkins流水线脚本 从sonar代码扫描,到maven构建,到docker打包,到k8s发布
查看>>
微服务项目占用内存过多机器扛不住怎么办?服务allinone设计
查看>>
项目快速开发经验
查看>>
LambdaQueryWrapper动态加过滤条件 动态Lambda(首发)
查看>>
javascript 大数值进行按位运算
查看>>
jacob 设置 插入word 的图片大小
查看>>
html2image html转换为图片 生成快照 java
查看>>
GPRS+wifi 云巡更系统开放sdk api 可以和OA CRM 对接巡更系统
查看>>
浏览器页面之间推送消息 A窗口给B窗口推送消息 用于cef多个browser之间通信
查看>>