Android 12上全新的应用启动画面,适配一下? - 程序师
文章推薦指數: 80 %
早期的Android上App的启动速度常为人诟病,如今的启动表现已不逊iOS。
Google针对系统的不断优化绝对功不可没,从8.0独立出来的SplashWindow,到12上推出的 ...
早期的Android上App的启动速度常为人诟病,如今的启动表现已不逊iOS。
Google针对系统的不断优化绝对功不可没,从8.0独立出来的SplashWindow,到12上推出的全新SplashScreen。
在App的主要内容展示之前,按照需求的不同,或多或少会先展示这样几个画面。
画面
用途
SplashScreen
展示品牌Logo或Slogan
AdvertisementScreen
展示节日活动或日常广告
GuideScreen
演示重点功能,一般只展示一次
启动过程示意图
1前言
我们常常花费精力去打造引导画面或广告画面,而作为第一印象的启动画面却容易被忽视。
回想下以前都是怎么处理这个画面的:
一般通过设置windowSplashscreenContent属性来展示UI提供的启动图,系统将为它创建专门的Window
假使忘记设置这个属性的话,默认的白色背景将导致启动过程中会有个白画面一闪而过
要去掉这个突兀的白画面可不能简单地设置Background为null,不然一闪而过的又会变成黑画面
最终发现windowDisablePreview属性可以彻底关闭这个画面,这样一来确实没有任何突兀的画面一闪而过了
但这又会带来启动”变慢”的副作用,因为用来过渡的启动画面被关闭之后,App描画前屏幕几乎没有什么变化。
即便App性能没有劣化,但为了留住用户,我们还是得好好对待这个启动画面。
然而现有的windowSplashscreenContent可供定制的空间着实有限。
也许官方也注意到了这点,便精心设计了SplashScreen API,并在Android12里重磅推出。
有了这个全新特性的帮助,启动画面的定制将更加自由、方便。
先来看下采用SplashScreenAPI快速定制的启动效果。
下面将逐步演示全新SplashScreen可供定制的各个方面。
2定制进入效果
采用xml即可快速定制各式进入效果。
2.1默认的启动效果
默认情况下启动画面将展示白色背景和Launcher上的AdaptiveIcon,也是不错的,比以前的白画面好很多。
2.2自定义静态Icon
替换Icon为AdaptiveIcon的前景图,背景色微调为米黄色。
再比如让机器人在Kotlin上侧滑。
或者让几何图案拼凑出字母K之后和机器人汇合,象征着Android和Kotlin的强强联合。
注意:
动画Icon的时长上限为1000ms。
图标的进入动画可以定制,但由系统控制,不可以被监听和额外处理。
2.6延长启动画面
Thesplashscreenisdismissedassoonasyourappdrawsitsfirstframe.Ifyouneedtoloadasmallamountofdatasuchasin-appthemesettingsfromalocaldiskasynchronously,youcanuseViewTreeObserver.OnPreDrawListenertosuspendtheapptodrawitsfirstframe.
后台数据的加载难免耗时,启动画面结束了主要内容仍未加载好的话,体验不是太好。
能够控制启动画面的持续时时长就好了。
现有的ViewTreeObserver的OnPreDrawListener回调是可以挂起描画的,如果我们在数据准备好之后再放行描画,就可以间接地延长启动画面的显示。
比如Activity初始化2s后才放行描画。
class SplashActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
...
keepSplashScreenLonger()
}
private fun keepSplashScreenLonger() {
// 监听Content View的描画时机
val content: View = findViewById(android.R.id.content)
content.viewTreeObserver.addOnPreDrawListener(
object : ViewTreeObserver.OnPreDrawListener {
override fun onPreDraw(): Boolean {
// 准备好了描画放行,反之挂起
return if (viewModel.isDataReady()) {
content.viewTreeObserver.removeOnPreDrawListener(this)
true
} else {
false
}
}
}
)
}
}
class MyViewModel(application: Application): AndroidViewModel(application) {
companion object {
const val WORK_DURATION = 2000L
}
private val initTime = SystemClock.uptimeMillis()
fun isDataReady() = SystemClock.uptimeMillis() - initTime > WORK_DURATION
}
看一下效果,发现启动画面的展示时间确实变长了。
3定制退出效果
当App的第一帧开始描画,SplashScreen将会退出展示。
为了丰富退出环节的体验,系统也开放了相应的入口,即画面退出的回调。
在这个回调里可以开始退出效果的定制,包括整体的退出动画和图标的退出动画。
3.1监听启动画面的退出
向SplashScreen注册OnExitAnimationListener接口即可监听启动画面的退出。
override fun onCreate(savedInstanceState: Bundle?) {
...
customizeSplashScreenExit()
}
private fun customizeSplashScreenExit() {
splashScreen.setOnExitAnimationListener { splashScreenView ->
Log.d("Splash", "SplashScreen#onSplashScreenExit view:$splashScreenView")
sleep(1000)
Log.d("Splash", "SplashScreen#remove after sleeping")
splashScreenView.remove()
}
}
可以看到启动画面展示之后,不作定制的默认情况下就是全屏一下再消失。
日志如下:
Splash : Activity:com.example.splash.MainActivity@f70c0d0 Activity:com.example.splash.MainActivity@f70c0d0 onCreate
Splash : Activity:com.example.splash.MainActivity@f70c0d0 onStart
Splash : Activity:com.example.splash.MainActivity@f70c0d0 onResume
Splash : SplashScreen#onSplashScreenExit view:android.window.SplashScreenView{18339d5 V.E...... ........ 0,0-1080,2280}
Splash : SplashScreen#remove after sleeping
一定记得调用remove及时移除启动画面,否则SplashScreen会长时间盖在主画面上,大概在5s左右。
另外,回调的注册需要放在Activity#onResume前,不然监听不到。
3.2定制整体的退出动画
可以给启动画面的整体设置TRANSLATE、SCALE、ROTATE、ALPHA等各种动画,使得退出更加自然。
比如给SplashScreen加上一个缩小出屏幕的动画。
private fun customizeSplashScreenExit() {
splashScreen.setOnExitAnimationListener { splashScreenView ->
showSplashExitAnimator(splashScreenView)
}
}
private fun showSplashExitAnimator(splashScreenView: SplashScreenView) {
val path = Path()
path.moveTo(1.0f, 1.0f)
path.lineTo(0f, 0f)
val scaleOut = ObjectAnimator.ofFloat(
splashScreenView,
View.SCALE_X,
View.SCALE_Y,
path
)
...
scaleOut.doOnEnd {
splashScreenView.remove()
}
scaleOut.start()
}
又或者从上方平移出屏幕的动画。
private fun showSplashExitAnimator(splashScreenView: SplashScreenView) {
val slideUp = ObjectAnimator.ofFloat(
splashScreenView,
View.TRANSLATION_Y,
0f,
-splashScreenView.height.toFloat()
)
...
slideUp.start()
}
3.3定制图标的退出动画
当然也可以给图标单独加上动画,比如将Icon上滑。
private fun customizeSplashScreenExit() {
splashScreen.setOnExitAnimationListener { splashScreenView ->
showSplashIconExitAnimator(splashScreenView)
}
}
private fun showSplashIconExitAnimator(splashScreenView: SplashScreenView) {
val iconView = splashScreenView.iconView ?: return
val slideUp = ObjectAnimator.ofFloat(
splashScreenView.iconView,
View.TRANSLATION_Y,
0f,
-iconView.height * 2.toFloat()
)
...
slideUp.start()
}
3.4退出动画的适当时长
针对退出动画的定制官方还有一段补充说明。
Bythestartofthiscallback,theanimatedvectordrawableonthesplashscreenhasbegun.Dependingonthedurationoftheapplaunch,thedrawablemightbeinthemiddleofitsanimation.UseSplashScreenView.getIconAnimationStarttoknowwhentheanimationstarted.Youcancalculatetheremainingdurationoftheiconanimation.
简言之,退出画面回调的时候Icon动画可能进行到了一半,最好计算Icon动画的剩余时长来执行退出动画。
原因在于设备性能会影响App描画的早晚,而第一帧描画的时候上述的退出回调将被执行。
也就是说,性能的优劣会影响启动画面退出的回调时机。
性能好的话,画面退出的回调较早。
此时Icon动画尚在进行当中,可以将Icon动画的预设时长的剩余时间交接给退出效果来执行
性能差的话,画面退出的回调稍晚。
Icon动画早已经结束,为了让用户尽早看到画面内容,就不该再执行退出效果了而是直接退出
不能为了展示效果而让用户久等,否则会弄巧成拙。
借助SplashScreenView的iconAnimationStartMillis和iconAnimationDurationMillis方法可以推算出Icon动画的剩余时长。
*模拟器上运行的缘故,大部分时候我的Demo在启动画面退出的时候Icon动画都结束了,少部分情况下动画还剩余一点时间,可能实机的情况会不一样。
private fun showSplashIconExitAnimator(splashScreenView: SplashScreenView) {
slideUp.duration = getRemainingDuration(splashScreenView)
...
}
fun getRemainingDuration(splashScreenView: SplashScreenView): Long {
// 取得Icon动画的时长
val animationDuration = splashScreenView.iconAnimationDurationMillis
// 取得Icon动画的开始时刻
val animationStart = splashScreenView.iconAnimationStartMillis
// 再结合当前时间计算出Icon动画的剩余时长
// 1. 时长为负则固定为0ms即直接退出
// 2. 时长为正则采用该时长执行退出动画
return if (animationDuration != null && animationStart != null) {
(animationDuration - SystemClock.uptimeMillis() + animationStart)
.coerceAtLeast(0L)
} else {
0L
}
}
4SplashScreen相关API
4.1类和接口
类/接口
作用
SplashScreen
启动画面管理接口,通过Activity#getSplashScreen取得
OnExitAnimationListener
启动画面退出的回调接口,通过SplashScreen#setOnExitAnimationListener注册
SplashScreenView
启动画面包含的视图,用以定制整体或Icon的退出动画
4.2属性
attr
作用
备注
splashScreenTheme
指定SplashScreen相关的Style
存在一点显示问题
windowSplashScreenBackground
启动画面的背景颜色
默认读取Background
windowSplashScreenBrandingImage
指定启动画面底部的品牌Logo
–
windowSplashScreenAnimatedIcon
指定Icon,支持静态或动画Drawable
–
windowSplashScreenAnimationDuration
指定动画Icon时长
上限1000ms
windowSplashScreenIconBackgroundColor
补充Icon背景
–
注意:windowSplashscreenContent是8.0版本新增的定制启动画面的属性,自12开始废弃了,使用windowSplashscreenAnimatedIcon替代
4.3SplashScreen的构成
启动画面构成图
5注意
需要尝鲜SplashScreen的话,需要在Android12上开发,并做如下必要配置。
compileSdkVersion和targetSdkVersion声明为S
android:exported="true",明示声明启动画面的可见性,否则会安装失败
另外启动页的Icon无论是静态的还是动画效果的,都应遵循AdaptiveIcon的规范,不然Icon会发生变形。
6结语
Android12上全新的SplashScreenAPI非常简单清晰,整个定制过程非常流畅!
相信在全新的API加持下,APP的启动画面可以迸发出更多特色的、好玩的创意。
快快尝试起来,给你的用户留下第一眼的好印象~
本文DEMO
https://github.com/ellisonchan/SplashScreen
参考资料
https://developer.android.google.cn/about/versions/12/features/splash-screen
https://developer.android.google.cn/reference/android/window/SplashScreen
本文文字及图片出自微信公众号
余下全文(1/3)
分享这篇文章:
相关文章:
在谷歌刚发布的安卓13里,我又找到了华为的技术。
。
。
为啥小米开发者提交了两行代码就被网友喷了?
小米提议禁止安卓手机提取APK文件,遭谷歌驳回
最新一代安卓系统来了!安卓12新特性详细解析
谷歌正式发布Android12:可谁又在乎呢?
“反安卓”联盟往事
在安卓项目里部署so文件你需要知道的知识
谷歌收购Android图形驱动测试公司GraphicsFuzz
谷歌为什么要对Android的开源严防死守?
若欧盟真重罚谷歌50亿美元Android将会发生这些改变
你的反应是:
0
俺的神呀0
赞一个0
飘过~0
强0
很实用0
好文0
笑死了0
mark0
敬佩0
垃圾0
0
看样子你已经点过这个了!
抱歉,你最多只能点三个!
请关注我们:
文章导航
上一文章谷歌要用SoC代替主板了吗?下一文章Python之父:让Python快2倍
发表评论取消回复
邮箱地址不会被公开。
必填项已用*标注评论名称*
站点
电子邮件*
益智游戏
趣味益智互动游戏:请画一个小人!
趣味益智互动游戏:请画一个小人!
益智游戏
测试:你的眼睛对颜色敏感吗?!测一测你能得多少分。
你的眼睛对颜色敏感吗?!测一测你能得多少分。
业界观察
LinusTorvalds:我不再了解编程,不再是一名程序员了
Torvalds解释说,他不再了解编码了,目前写的大多数代码都在电子邮件中。
每当有人发送了补丁,他就用伪代码回复
业界观察
如果阿里月饼黑客事件发生在谷歌会怎样?前Google人亲述他抢了50件T-shirt的故事
本文作者吴卓浩,前Google中国用户体验团队负责人。
业界观察
搞笑视频:JavaScript才是真正的老大
《掌掴》JavaScript篇
业界观察
雷军22年前写的代码你见过吗?
网上出现一篇“刘强东的代码水平如何”的文章,有网友在下面回复“代码只服雷军”。
这个回复吸引了小编的注意,雷军的代码水平真的很牛吗?
业界观察
趣图:想搞机器学习,数学总是障碍
这是机器学习和数学的关系
编程技术
javascript中的错误处理
这是关于JavaScript中异常处理的故事。
如果你相信墨菲定律,那么任何事情都可能出错,不,一定会出错!这篇文章中我们来看下JavaScript中的出错处理。
文章会覆盖异常处理使用的正反例,然后看下ajax的异步处理。
业界观察
为什么是Go而不是Rust
Rust是一个更好的C++,即使你偶尔听到有人说Go是一个更好的C,但事实并非如此。
任何带有内置垃圾收集器和运行时的语言,都不能被视为C语言。
别搞错了,Rust才是C++,而不是C。
业界观察
2019年谁在寻找Docker职位,谁又在雇佣Docker职员?
人均年薪80万以上,50%的职位空缺,Docker入坑不亏?
业界观察
每个程序员都需要掌握的30件事
从事编程并不容易。
每年有许多人从各国的顶级计算机科学专业毕业,这是所有人都向往的有竞争力的职业之一。
与此同时,编程也振奋人心。
随着技术的进步,每天都有新的创新。
对于喜欢编程,并立志从事编程的人而言,编程是其热爱且为之奋斗的事业。
程序人生
要嫁就嫁程序猿——钱多话少死的早
我是一个苦b的程序员,今晚加班到快通宵了,困得快睁不开眼了,女上司很关心,问我要不要吃宵夜。
我没好气地说,宵夜就算了,能让我睡一觉就行了。
女上司红着脸说了句讨厌
×
感谢你的参与互动。
姓名*
电子邮件*
输入有误!
延伸文章資訊
- 1Android添加全屏啟動畫面 - 程式人生
全屏quest ray class max-width pub title nbsp hello. 有的Android軟件需要在啟動的時候顯示一個啟動畫面,可以是一張圖或者一些設置什麽呢,還有 ...
- 2啟動畫面
重要事項: 如果您先前已在Android 11 或以下版本中實作了自訂啟動畫面,就必須將應用程式遷移至 SplashScreen API,以確保其可在Android 12 及以上 ...
- 3帶動畫的啟動畫面- android - 他山教程
此示例顯示了一個簡單但有效的啟動畫面,其中包含可以使用Android Studio 建立的動畫。 第1 步:建立動畫. 在res 目錄中建立一個名為anim ...
- 4Android Splash Screen 啟動畫面| Android Fly程式筆記
現在市面上的Android打開的時候,大部分都會有Splash 啟動畫面,Splash是等待裡面的處理程序處理好以後,再打開程式,創建一個新的Androoid Splash ...
- 5如何建立登入過程的畫面(SplashScreen)
其實會需要啟動畫面有一種說法是早期PC時代由於記憶體很少要載入到作業系統需要 ... <RelativeLayout xmlns:android="http://schemas.android....