在webview的build方法中,可以看到通过WebView.platform.build传入构造的参数,然后判断平台返回对应视图。
/// webview_flutter/webview_flutter/lib/src/webview.dart
@override
Widget build(BuildContext context) {
return WebView.platform.build(
context: context,
onWebViewPlatformCreated: _onWebViewPlatformCreated,
webViewPlatformCallbacksHandler: _platformCallbacksHandler,
javascriptChannelRegistry: _javascriptChannelRegistry,
gestureRecognizers: widget.gestureRecognizers,
creationParams: _creationParamsfromWidget(widget),
);
}
/// 根据设备类型返回对应的视图
static WebViewPlatform get platform {
if (_platform == null) {
switch (defaultTargetPlatform) {
case TargetPlatform.android:
_platform = AndroidWebView();
break;
case TargetPlatform.iOS:
_platform = CupertinoWebView();
break;
default:
throw UnsupportedError(
“Trying to use the default webview implementation for $defaultTargetPlatform but there isn’t a default one”);
}
}
return _platform!;
}
/// 设置参数,这里我加多了一个transparentBackground参数,是bool类型的
CreationParams _creationParamsfromWidget(WebView widget) {
return CreationParams(
initialUrl: widget.initialUrl,
webSettings: _webSettingsFromWidget(widget),
javascriptChannelNames: _extractChannelNames(widget.javascriptChannels),
userAgent: widget.userAgent,
autoMediaPlaybackPolicy: widget.initialMediaPlaybackPolicy,
transparentBackground: widget.transparentBackground,
);
}
以Android为例,来到webview_flutter_android的webview_android.dart中。可以看到通过AndroidView引入原生视图,通过标识 ‘plugins.flutter.io/webview’ 进行匹配。
/// webview_flutter/webview_flutter_android/lib/webview_android.dart
return GestureDetector(
onLongPress: () {},
excludeFromSemantics: true,
child: AndroidView(
viewType: ‘plugins.flutter.io/webview’,
onPlatformViewCreated: (int id) {
if (onWebViewPlatformCreated == null) {
return;
}
onWebViewPlatformCreated(MethodChannelWebViewPlatform(
id,
webViewPlatformCallbacksHandler,
javascriptChannelRegistry,
));
},
gestureRecognizers: gestureRecognizers,
layoutDirection: Directionality.maybeOf(context) ?? TextDirection.rtl,
creationParams:
MethodChannelWebViewPlatform.creationParamsToMap(creationParams),
creationParamsCodec: const StandardMessageCodec(),
),
);
之后进入android目录,找到对应的FlutterWebView文件,通过获取methodcCannel传入的params来判断是否需要启用透明背景,如果为true,则设置backgroundColor为透明。
Ps:这里可以看出,原生插件的编写很简单。只要通过methodChannel进行通信,Flutter层传入params,原生层获取参数后进行解析。注意数据传输都是转为字符串类型的,甚至很多时候都是用json字符串流转。
同时这里也返回了原生视图,通过PlatformView绑定标识,返回对应PlatformViewFactory的视图,标识同样也是字符串类型。
所以是非常傻瓜式的,Flutter只不过提供了一个通信桥梁来实现跨平台,原生代码还是得自己写,从这个角度来看,Flutter真的跨平台了吗?积极开源的社区对于Flutter而已,必要性何其重呢?值得我们深思!
ios端也一样,核心代码就是修改wkWebview的背景色为透明
/// webview_flutter/webview_flutter_wkwebview/ios/Classes/FlutterWebView.m
NSNumber* transparentEnabled = args[@“transparentBackground”];
NSLog(@“transparentBackground >>> %i”, [transparentEnabled boolValue]);
// 设置背景色为透明
if([transparentEnabled boolValue]){
NSLog(@“开始设置背景色”);
_webView.opaque = NO;
_webView.backgroundColor = UIColor.clearColor;
}
重点:如何引入到项目中使用并且独立维护
功能实现完,要考虑如何引入到我们的项目中使用。以往个人开发的插件一般都是通过git仓库引入,所以我创建新的GitHub仓库,把改好的webview目录整个上传上去。加入项目中flutter pub get后惊喜的发现,失败了!
原因是:根目录下没有yaml文件,对于Flutter来说是一个不合格的Plugin。 所以我们需要指定插件的根目录,通过path来指定到webview文件夹下。
webview组件
webview_flutter:
git:
url: git://github.com/~~~/webview_flutter_enable_transparent.git
ref: main
path: webview_flutter # 指定路径
继续get,再次惊喜!!! 原因是:相对路径 …/XXXX 找不到对应的插件,这合理吗?
很合理,因为Flutter必须保证你的包是最小的,你既然指定了依赖的库,那我就只会下载对应的库,并不是整个git下载下来。所以我们用相对路径的时候,根本找不到根目录下其他的插件。
解决方法,webview的yaml文件中所依赖的插件也需要用git引入
dependencies:
flutter:
sdk: flutter
webview_flutter_platform_interface:
git:
url: https://github.com/~~~/webview_flutter_enable_transparent.git
ref: main
path: webview_flutter_platform_interface
webview_flutter_android:
git:
url: https://github.com/~~~/webview_flutter_enable_transparent.git
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!**
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!