参考文章

Flutter 开发 Android & IOS 启动页 splash pag
Flutter 启动页(闪屏页)具体实现和原理分析
Flutter启动流程和原理分析

需要知道的

  1. iOS13 开始 苹果要放弃LaunchImage适配启动图 , 改为必须走LaunchScreen.sb来启动
    所以在iOS端,启动图适配,要么使用LaunchScreen.sb 内嵌UIImageView +AutoLayout 来适配(依旧使用整图), 要么就采用 页面布局的方式, 来开发启动页,具体可以参考下面这个链接
    iOS 13使用LaunchScreen.storyboard适配各尺寸启动图

  2. Flutter 的启动顺序,或者说是启动过程
    iOS和Android端的原理其实是一样的, Android的MainActivity继承了FlutterActivity,FlutterActivity又通过FlutterActivityDelegate实现了生命周期的代理, 就是创建一个View并通过MainActivity的onCreate方法去加载显示出来,
    同样的, iOS端也在AppDelegate中处理, AppDelegate: FlutterAppDelegate

所以总结来说, Flutter 的启动顺序依然和RN 一样, 先是各自从原生的Launch启动, 这一部分是iOS/Android原生处理,属于冷启动过程(机器不行就会等待较长时间), 还没有涉及到Flutter部分, 如果不做处理,将会有白屏或者黑屏短暂出现,
直到到Flutter层页面被加载出来, 此时启动就算结束了

  1. Flutter 接管后, 是否需要一个Flutter层面的启动页?
    一般来说,Flutter确实需要这么一个Flutter层面的启动页,
    从刚才的原生层启动后, 按道理就是进入Flutter页面了,内容也都呈现了 为什么说通常意义还需要一个Flutter层面的启动页呢?
    这是因为,一般我们需要在Flutter层面做一些同步耗时的操作, 比如两步认证/token验证/App状态检测等等, 有一个启动页帮助我们缓冲一下,相对比较合适…

举个例子(不算恰当), App登录已超时,如果App启动后直接进入首页, 然后由于某些原因必须退出到登录页, 这样的交互显的不那么完美, 最好的是在启动前,就能从接口处得知登录状态, 若登录失效,就直接进入登录页面,未失效就直接进入首页进行业务处理,
所以,请求的过程放到Flutter的启动页, 会显得比较合适

  1. 由于iOS的冷启动采用页面布局的方式实现(放弃LaunchImage的图片适配方式), 建议Flutter层面的启动页面, 也通过页面布局方式(偷懒就丢一整张图)
    这样适配起来可控, 能做到肉眼不可查, 放图片的话,又是要进行图片的适配,反而麻烦

开始吧

1.首先因为启动图比较简单, 我这边就找UI给了2x/3x 的两个图, 分别在iOS原生层和Flutter层添加这两张图片作

iOS原生启动

图片

(截图有点早, 其实这边包括后面Flutter , 都是讲图片居于底部居中的布局方式,此处就不另行截图了)

iOS端冷启动页面比较简单,就在LaunchScreen.sb中放一个UIImageView, 做好约束就可以了,我这边因为启动页比较简单, 就让UI切一张图即可,背景色到时候改成白色基本就看不出来了,
图片的填充模式记得选择 Aspect Fill 填充


Android 原生启动

一个插曲…
刚开始使用AS创建Flutter项目的时候, 它默认创建的android/iOS ,分别是Kotlin和swift 模式, 鉴于对kotlin的不熟悉, 需要换成java的版本, 所以可以删除掉项目文件夹下的 android 文件,然后再终端重新创建一下
查看一下Flutter 的命令行工具
ruby flutter create -h

可以看到, 创建的默认就是 swift/ kotlin , 需要切换的就可以切换一下

修改Android ruby create -a java .
修改iOS ruby create -i objc

切换过后,
创建好的文件就便是纯java的了, 当然一些文件和配置, 就需要重新设置了…

安卓部分


如上图部分, FLutter 会在 AndroidManifest.xml中指定好Launch启动页入口

            <!-- Displays an Android View that continues showing the launch screenDrawable until Flutter paints its first frame, then this splashscreen fades out. A splash screen is useful to avoid any visualgap between the end of Android's launch screen and the painting ofFlutter's first frame. --><meta-dataandroid:name="io.flutter.embedding.android.SplashScreenDrawable"android:resource="@drawable/launch_background"/>

所以我们可以在launch_background.xml中进行编辑…
对了, 建议在编辑的时候用AS再单独打开android的工程, 不然直接用Flutter下的, 有点辅助显示和跳转都不支持…
一开始我还以为是哪里出了问题

<?xml version="1.0" encoding="utf-8"?><!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"><item android:drawable="@color/colorPrimaryDark" ></item><!-- You can insert your own image assets here --><!-- <item><bitmapandroid:gravity="center"android:src="@mipmap/launch_image" /></item> --><itemandroid:gravity="bottom"android:bottom="0pt"android:left="0pt"android:right="0pt"><bitmapandroid:src="@drawable/launch_icon" /></item>
</layer-list>

这里我对于xxxhdppi没有放图… 其实后期可以补上…, 但是相应的, 我们也要在Flutter下的4x文件夹放置对应图片

最后的效果是:

发现, 两个启动图还是不一致…

问题出在哪里… 我稍后排查下, 对于android, 还需要更多的学习…

Flutter阶段启动图

直接上代码吧, LaunchScreen.dart 中的build部分

  @overrideWidget build(BuildContext context) {// TODO: implement buildreturn Container(width: DeviceUtils.screenW,height: DeviceUtils.screenH,color: Color(0xffffffff),child: Stack(alignment: AlignmentDirectional.bottomCenter,children: [Positioned(child: Image.asset(ImagesPath.launch_icon,width: 750.px,height: 220.px,fit: BoxFit.fill,),bottom: 60.px,)],));}

一些遇到的问题

1. iOS / Flutter 加载的图片, 高度稍微有差异???

怀疑1
iOS原生和Flutter加载的图片不一样?
为了方便分析 , 干脆图片添加了不同文字来区分,
发现在iPhone 8 plus 上, iOS原生的LaunchScreen添加的是3x图片, Flutter的启动页面添加的是2x图片

原因是,

在Flutter 里面, 如下图, 我忘记去掉图片上面的@2x @3x, 导致Flutter只识别@2x图片, (果然Flutter是谷歌儿子, 玩法都是和安卓一样…), 我丢图的时候忘记修改名字了

同时, 我测试发现, 在src/img 下, 其实不必再放1x图片, 现在目前市面上主流手机都是2x图片起步, 所以我这样改造


pubspec.yaml中这样

  # 感觉目前手机(比如iOS, 1x的图片几乎没必要再使用了,因此此处img目录下直接存放2x图片,3x,4x图片通配)assets:- src/img/- src/img/3x/- src/img/4x/

iOS层和Flutter层中加载的均是3x图了


但是… 问题没有解决

怀疑2
高度单位换算问题
目前,单位换算基于iPhone6 的宽度 375 pt , 而高度的换算部分也基于375.
怀疑是高度换算不准确, 于是, 修改高度换算代码, 用667 pt 来进行换算, 具体实现网上都有, 这边给出log
原图的pt 是375 * 110 pt

    debugPrint(DeviceUtils.screenW.toString());debugPrint(DeviceUtils.screenH.toString());debugPrint(750.px.toString());debugPrint(220.px.toString());debugPrint(220.pxH.toString());
logiPhone8
flutter: 414.0
flutter: 736.0
flutter: 414.00000000000006
flutter: 121.44000000000001 220.px
flutter: 121.37931034482759 220.pxHiPhoneXR
flutter: 414.0
flutter: 896.0
flutter: 414.00000000000006
flutter: 121.44000000000001
flutter: 147.76611694152925

可以看到, 基于375 基于667 换算下来的高度几乎是一样的
(其实在 iPhone XR 上差异就大了)
问题依旧没有解决, 两个启动页面的图片高度还是有高度差异…
(测试发现 . 在iPhoneSE2, iPhoneX 是表现OK的)

然后我突然反应过来…
然后我突然反应过来…
然后我突然反应过来…
此处的图片高度, 根本就不能进行单位换算,
应该直接这样写
(目前这里因为只做了iOS侧, 所以先写110 , 代表110 pt)

           Positioned(child: Image.asset(ImagesPath.launch_icon,width: 750.px,height: 110,
//                height: 220.px,fit: BoxFit.fill,),bottom: 0.pxH,

这个110 和iPhone8 下的121.440000 仅相差10, 也符合我看到的,两个launch页面图片有细微的高度差的描述…

至于为什么不能进行单位换算?

因为在iOS 的LaunchScreen中, 我添加了这张375*110的图片,图片的高度是固定的, 就是110pt, 或者说220px ,
此时我无论是基于375 还是基于667 的基础进行单位换算, 其数值在8 / XR等机型上的高度被计算修改过了( 121.440000 等),
反而 在 iPhone se2 这样的机器上, 换算出来的高度正好就是110
那什么地方需要用到换算?
其他正常布局使用单位换算都可以, 但是遇到这种特殊的情况, 或者一些在各个机型上需要同样高度的, 就不推荐进行单位换算…

Flutter 层的启动页, 图片被挤压了


明显看到图片挤压了,有点变形, 是因为设置图片的填充模式

       fit: BoxFit.cover,

就可以了

Flutter 启动页适配相关推荐

  1. 使用Timer实现Flutter启动页

    在APP开发中,我们都会写一个启动页,这个启动页不仅可以作为广告投放点,也可以作为初始化数据的地方.那在Flutter中如何实现一个启动页呢?本文就为大家介绍一下使用Timer实现Flutter启动页 ...

  2. Flutter启动页白屏处理

    前言 在上篇实现了一个Nike的加载页,但有一些遗留问题,其中之一就是启动时的白屏处理.如下: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vX0WOEA6-1653 ...

  3. 开机动画适配方案_Android启动页适配

    1.theme 老实说我适配过好多次启动页,代码都丢失了,哈哈哈,每次都费老大劲,有的是laylist 有的是.9图片,这回我要说的是.9图片,不能说百分百适配啊 分辨率越高越明显 只能保证图标不变形 ...

  4. 应用全屏启动页适配小米9(水滴屏)

    启动页的简单制作 网上已经有这方面的教程,我选用的是我认为比较方便简单的方式,首先创建Activity: class LunchActivity : AppCompatActivity() {over ...

  5. flutter(1) 启动页 引导页

    flutter 启动页 引导页 Android 原生引导页面的方法如下 1 自定义 使用 ViewPager控件 2使用第三方 组建AppIntro AppIntro快速启动页面 flutter  引 ...

  6. android dialog 隐藏状态栏_Flutter-最近搞了个项目-启动页Splash,Navigator.pop无法关闭Dialog...

    上一篇做了个总体简单记录总结 MonkeyLei:Flutter-最近搞了个项目(常用控件,第三方基本库)-底部导航,登录,启动画面,webview等 . 完事了后以为没什么事情,然后点击登录会显示加 ...

  7. android 启动白屏_从细节入手改善用户体验,Flutter跨平台App开发中设置Android和iOS的启动页

    前言 flutter开发App方便快捷,就是冷启动的时候要加载dart引擎有短暂的白屏,严重影响用户体验,这个时候我们就需要设置一个启动图片,想国内大部分App那样(例如微信那个地球),启动App的时 ...

  8. android自适应拉伸图片,Android 启动页-解决图片被拉伸和压缩问题,适配虚拟导航栏...

    Android 启动页设置非常简单 //styles.xml 设置主题 @drawable/bg_splash true //activity使用主题,这时点击app图标,就会显示@drawable/ ...

  9. Flutter实战01 - 启动页 闪屏广告 引导页

    一个app通常都会有一个App通常都会有SplashPage页面,在这页面包含启动页.引导页(app简介说明).闪屏广告页(点广告页跳转到相应H5页面). 在Flutter实现引导页需要在Materi ...

  10. 手淘启动页全面屏和虚拟键适配

    背景 华为对新发布的机器进行适配测试,发现手淘存在全面屏适配问题,随后还附了个3页的文档,文档比较粗泛的描述了一下不适配将会存在的问题,适配可以采取的措施,以及Google开发者文档.简单来说,因为全 ...

最新文章

  1. 用户组管理之删除分组表数据
  2. 在有序数字中寻找和为k的两个数 O(n)
  3. 莫名的_locals属性
  4. SQL Server Mysql 对null值理解的不同
  5. Google Analytics 图文全攻略
  6. linux+sasl认证失败,51CTO博客-专业IT技术博客创作平台-技术成就梦想
  7. oracle将日期格式化to_char及字符串转日期to_date
  8. 基于Keras机器学习库的分类预测
  9. Jave基本知识(一)
  10. Python系列之Python-docx生成运行日报Word模板
  11. 关于方志鹏博主springcloud系列教程提示:Could not resolve placeholder 'foo' in value ${foo}报错
  12. dataworks 生成表血缘依赖
  13. c# 编写水准测量平差程序
  14. JAVA启动杀怒尖塔_杀戮尖塔如何修改class 杀戮尖塔修改class文件方法步骤图解
  15. 搭建微信小程序HTTPS服务器
  16. 富康路小学毕业郭佳华
  17. 抖音数据 - 网民评论数据采集,分析
  18. 浏览器历史记录的模式
  19. QQ上保险我的QQ密码谁也偷不走
  20. datasets DatasetDict类

热门文章

  1. 锁相环倍频原理简要分析
  2. IP地址、网络地址、网关的作用
  3. 关于diskpart的命令问题记录
  4. 泰克Tektronix示波器软件TDS420|TDS430|TDS460上位机软件NS-Scope
  5. python 时间戳转各时区时间
  6. SIP12 脚 电磁隔离放大器IC 模拟信号隔离放大器 电磁耦合隔离放大器
  7. 微信登录优化方案设计
  8. BD-rate计算方法
  9. PointRCNN:3D Object Proposal Generation and Detection from Point Cloud
  10. 泰凌微8258入门教程 问题篇②——make Error, section .text loaded at [x,x] overlaps section .retention_data loaded