资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

flutter开关,flutternutter

Flutter 之 CupertinoSwitch (iOS风格)(六十六)

CupertinoSwitch 是 iOS 风格的 switch 开关,相当于 UISwitch。

创新互联专注于双湖网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供双湖营销型网站建设,双湖网站制作、双湖网页设计、双湖网站官网定制、小程序定制开发服务,打造双湖网络公司原创品牌,更为您提供双湖网站排名全网营销落地服务。

CupertinoSwitch 定义

CupertinoSwitch

Flutter笔记-调用原生IOS高德地图sdk

2017年底因公司业务组合部门调整,新的团队部分维护的项目用React Native技术混合开发。为适应环境变化,开启疯狂RN学习之旅,晚上回来啃资料看视频。可能由于本身对RN技术体验不感冒或者在环境之下强迫学习有点不爽。开始寻找代替方案,Fluter像一束曙光引起了我的注意,之后一直关注并利用闲余时间开始探索。2018年一直学习到使用Flutter写项目,从0.2.0开始到现在1.5版本的发布,终于开始慢慢的爬出坑位了,但是因为部分控件感觉还是不如原生控件好用,因而Flutter提供了PlatformView部件。近期因项目中严重使用依赖地图,故而做了Fluterr使用原生IOS高德地图调研。因为我本身是一名android开发人员,初学IOS并记录下来。

PlatformView是 flutter 官方提供的一个可以嵌入 Android 和 iOS 平台原生 view 的小部件。

在我们实际开发中,我们遇到一些 flutter 官方没有提供的插件可以自己创建编写插件来实现部分功能,但是原生View在 flutter 中会遮挡住flutter 中的小部件,比如你想使用高德地图sdk、视频播放器、直播等原生控件,就无法很好的与 flutter 项目结合。

1、info.plist文件设置

2、 ios 端实现原生组件PlatformView提供原生view

3 、ios 端创建PlatformViewFactory用于生成PlatformView

4、 ios 端创建FlutterPlugin用于注册原生组件

5 、flutter 平台嵌入 原生view

iOS端的UiKitView目前还只是preview状态, 默认是不支持的, 需要手动打开开关, 在info.plist文件中新增一行io.flutter.embedded_views_preview为true.

创建类 FlutterMapView 并实现FlutterPlatformView 协议

FlutterMapView.h

FlutterMapView.m

FlutterMapFactory.h

FlutterMapFactory.m

FlutterMapPlugin.h

FlutterMapPlugin.m

请前往 高德开放平台控制台 申请 iOS Key。

注意:Bundle Identifier需要与申请的时候填写的一致

地图依赖的库列举如下:

基础 SDK AMapFoundationKit.framework

第一步:将解压后的MAMapKit.framework 文件 copy 或 拖拽 到工程文件夹中,左侧目录选中工程名,在 TARGETS-Build Phases- Link Binary With Libaries 中点击“+”按钮,在弹出的窗口中点击“Add Other”按钮,选择工程目录下的 MAMapKit.framework 文件添加到工程中。

千万不要忘记将AMapFoundationKit也一起加入工程。

3D地图正确配置应如下图所示:

需要引入的资源文件包括:AMap.bundle,其中:AMap.bundle 在 MAMapKit.framework 包中,AMap.bundle资源文件中存储了定位、默认大头针标注视图等图片,可利用这些资源图片进行开发。

左侧目录中选中工程名,在右键菜单中选择Add Files to “工程名”…,从MAMapKit.framework中选择AMap.bundle文件,并勾选“Copy items if needed”复选框,单击“Add”按钮,将资源文件添加到工程中。

成功跑起来 。。 。

Flutter 启动页的前世今生适配历程

APP 启动页在国内是最常见也是必备的场景,其中启动页在 iOS 上算是强制性的要求,其实配置启动页挺简单,因为在 Flutter 里现在只需要:

一般只要配置无误并且图片尺寸匹配,基本上就不会有什么问题, 那既然这样,还有什么需要适配的呢?

事实上大部分时候 iOS 是不会有什么问题, 因为 LaunchScreen.storyboard 的流程本就是 iOS 官方用来做应用启动的过渡;而对于 Andorid 而言,直到 12 之前 windowBackground 这种其实只能算“民间”野路子 ,所以对于 Andorid 来说,这其中就涉及到一个点:

所以下面主要介绍 Flutter 在 Android 上为了这个启动图做了哪些骚操作~

在已经忘记版本的“远古时期” , FlutterActivity 还在 io.flutter.app.FlutterActivity 路径下的时候,那时启动页的逻辑相对简单,主要是通过 App 的 AndroidManifest 文件里是否配置了 SplashScreenUntilFirstFrame 来进行判断。

在 FlutterActivity 内部 FlutterView 被创建的时候,会通过读取 meta-data 来判断是否需要使用 createLaunchView 逻辑 :

是不是很简单,那就会有人疑问为什么要这样做?我直接配置 Activity 的 android:windowBackground 不就完成了吗?

这就是上面提到的时间差问题, 因为启动页到 Flutter 渲染完第一帧画面中间,会出现概率出现黑屏的情况,所以才需要这个行为来实现过渡 。

经历了“远古时代”之后, FlutterActivity 来到了 io.flutter.embedding.android.FlutterActivity , 在到 2.5 版本发布之前,Flutter 又针对这个启动过程做了不少调整和优化,其中主要就是 SplashScreen 。

自从开始进入 embedding 阶段后, FlutterActivity 主要用于实现了一个叫 Host 的 interface ,其中和我们有关系的就是 provideSplashScreen 。

默认情况下它会从 AndroidManifest 文件里是否配置了 SplashScreenDrawable 来进行判断 。

默认情况下当 AndroidManifest 文件里配置了 SplashScreenDrawable ,那么这个 Drawable 就会在 FlutterActivity 创建 FlutterView 时被构建成 DrawableSplashScreen 。

DrawableSplashScreen 其实就是一个实现了 io.flutter.embedding.android.SplashScreen 接口的类,它的作用就是:

之后 FlutterActivity 内会创建出 FlutterSplashView ,它是个 FrameLayout。

FlutterSplashView 将 FlutterView 和 ImageView 添加到一起, 然后通过 transitionToFlutter 的方法来执行动画,最后动画结束时通过 onTransitionComplete 移除 splashScreenView 。

所以整体逻辑就是:

当然这里也是分状态:

当然这个阶段的 FlutterActivity 也可以通过 override provideSplashScreen 方法来自定义 SplashScreen 。

看到没有,做了这么多其实也就是为了弥补启动页和 Flutter 渲染之间, 另外还有一个优化,叫 NormalTheme 。

通过该配置 NormalTheme ,在 Activity 启动时,就会首先执行 switchLaunchThemeForNormalTheme(); 方法将主题从 LaunchTheme 切换到 NormalTheme 。

大概配置完就是如下样子, 前面分析那么多其实就是为了告诉你,如果出现问题了,你可以从哪个地方去找到对应的点 。

讲了那么多, Flutter 2.5 之后 provideSplashScreen 和 io.flutter.embedding.android.SplashScreenDrawable 就被弃用了,惊不喜惊喜,意不意外,开不开心 ?

通过源码你会发现,当你设置了 splashScreen 的时候,会看到一个 log 警告:

为什么会弃用?

其实这个提议是在 这个 issue 上,然后通过 这个 pr 完成调整。

大概意思就是: 原本的设计搞复杂了,用 OnPreDrawListener 更精准,而且不需要为了后面 Andorid12 的启动支持做其他兼容,只需要给 FlutterActivity 等类增加接口开关即可 。

也就是2.5之后 Flutter 使用 ViewTreeObserver.OnPreDrawListener 来实现延迟直到加载出 Flutter 的第一帧。

为什么说默认情况? 因为这个行为在 FlutterActivity 里,是在 getRenderMode() == RenderMode.surface 才会被调用,而 RenderMode 又和 BackgroundMode 有关心 。

所以在 2.5 版本后, FlutterActivity 内部创建完 FlutterView 后就会执行一个 delayFirstAndroidViewDraw 的操作。

这里主要注意一个参数: isFlutterUiDisplayed 。

当 Flutter 被完成展示的时候, isFlutterUiDisplayed 就会被设置为 true。

所以当 Flutter 没有执行完成之前, FlutterView 的 onPreDraw 就会一直返回 false ,这也是 Flutter 2.5 开始之后适配启动页的新调整。

看了这么多,大概可以看到其实开源项目的推进并不是一帆风顺的,没有什么是一开始就是最优解,而是经过多方尝试和交流,才有了现在的版本,事实上开源项目里,类似这样的经历数不胜数:


网站名称:flutter开关,flutternutter
本文路径:http://www.cdkjz.cn/article/dsseocj.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220