赞
踩
从 Android 12 开始,Android 强制启用全新的启动画面,有的APP有自己的启动页,这时候就会发现如果不做适配,启动应用时会先显示SplashScreen,然后再显示应用自己的启动页,比如
看上去会有点不协调,但现阶段没有方法可以禁用SplashScreen, 所以,还是有必要进行改造,正好例子应用本身的启动页和SplashScreen很相似,那就直接用SplashScreen版本好了。
考虑到在旧版本上还要继续使用原效果,所以只用判断在Android 12及以上使用SplashScreen即可:
- #在原有的启动页Activity里添加针对SplashScreen的处理
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
- getSplashScreen().setOnExitAnimationListener((splashScreenView) -> {
- //空实现,不消失splashScreenView
- });
- }
SplashScreen显示后会在应用绘制视图层第一帧之前完成并执行淡出动画,如果设置setOnExitAnimationListener,系统会将SplashScreenView回调给应用自己处理如何退出,我们可以设置一个空实现,这样一来SplashScreenView就会一直保留直到当前Activity退出,达到了仅显示SplashScreen而看不到自身启动页界面的效果(SplashScreen位于Activity上面,启动页被SplashScreenView遮住了)。
通过慢速播放启动视频发现,应用自己的启动页完成后跳转MainActivity会有短暂的黑屏,这个黑屏就是MainActivity界面还没绘制出来前的window背景,如果设备性能慢,黑屏显示时间越久,也不理想,能不能等MainActivity显示出来的时候再淡出SplashScreen呢?
答案是肯定的,在启动页我们不绘制视图层级,等到MainActivity绘制时即可。
修改之前的代码
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
- findViewById(android.R.id.content).getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
- @Override
- public boolean onPreDraw() {
- return false;
- }
- });
- }
原理就是欺骗ViewRootImpl我们还没准备好绘制,等跳转MainActivity开始绘制界面第一帧了,才触发SplashScreen的退出。
这部分可以看View的绘制过程,当Activity.onResume后会调用ViewRootImpl对象的performTraversals(),大概要执行如下步骤:
performTraversals -> 测量->布局->检查所有OnPreDrawListener是否都满足onPreDraw
->返回true->绘制
->有一个返回false->延迟短暂时间后重新performTraversals
过渡就很完美了 。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。