关于安卓12闪屏页适配(一)

背景

老生常谈的内容,启动页适配。
安卓12系统开始,启动app,系统就贴心给你上一个“系统级别”的启动页。遮住了原有的众多app中的启动闪屏页大部分事件。导致很多app的自定义闪屏页显示时间都缩短,甚至无法查看,因此需要进行适配。

环境

与环境无关,你项目能跑进行
编译sdk需要在12以上

思路

从官方的建议,有以下解决方法:
(1)旧业务全部转移到新适配启动页
(2)沿用旧的启动页(效果不是太好)
本文,将会使用(2)的方法折中实现。

实现思路

(一)引入splashscreen进行全方位适配
build.gradle
引入implementation “androidx.core:core-splashscreen:1.0.0”
启动页中,setContentView()方法前,调用方法:
installSplashScreen()
然后,设置SplashScreen对象的监听,如:
setOnExitAnimationListener()
setKeepOnScreenCondition()


setKeepOnScreenCondition是保持安卓12系统启动页的开关,代码如下:

mSplashScreen.setKeepOnScreenCondition(object : 
			SplashScreen.KeepOnScreenCondition {
                override fun shouldKeepOnScreen(): Boolean {
                    Log.d("Splash", "Splash shouldKeepOnScreen")
                    return false
                }
            })

return false代表不保持,return true代表保持。正常情况下,return 了false,就会触发方法:
setOnExitAnimationListener(),特殊情况,有些系统rom阉割了这一部分,就会没有这个回调,这个逻辑也是要纳入适配的范畴。
然后定义一个theme,用作启动页:

    <style name="Theme.Splash" parent="Theme.AppCompat.Light.NoActionBar">
        <!--启动画面背景颜色-->
        <item name="android:windowSplashScreenBackground">@color/purple_200</item>
        <!-- 启动画面icon图标:这里可以是图片、帧动画等-->
        <item name="android:windowSplashScreenAnimatedIcon">@color/purple_200</item>
        <!--        <item name="windowSplashScreenIconBackgroundColor">@null</item>-->
        <!-- icon动画在关闭之前显示的时长:最长时间为1000毫秒-->
        <item name="android:windowSplashScreenAnimationDuration">1000</item>
        <!-- Splash退出后的主题-->
        <item name="postSplashScreenTheme">@style/Theme.AndroidJiaguChannel</item>
    </style>

核心代码如下:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 初始化操作(必须放在setContentView()之前)
        val needToShow = isNeedShowSplash()
        val mSplashScreen: SplashScreen? = if (needToShow) installSplashScreen() else null
        setContentView(R.layout.activity_splash)
        if (needToShow && mSplashScreen != null) {
            // Splash展示完毕的监听方法
            mSplashScreen.setOnExitAnimationListener(object : SplashScreen.OnExitAnimationListener {
                override fun onSplashScreenExit(splashScreenViewProvider: SplashScreenViewProvider) {
                    Log.d("Splash", "Splash onSplashScreenExit")
                    mHadExitAnim = true
                    splashScreenViewProvider.remove()
                    toMainActivity()
                }
            })
            mSplashScreen.setKeepOnScreenCondition(object : SplashScreen.KeepOnScreenCondition {
                override fun shouldKeepOnScreen(): Boolean {
                    Log.d("Splash", "Splash shouldKeepOnScreen")
                    return false
                }
            })

            MainScope().launch {
                delay(200)
                if (mHadExitAnim) {
                    return@launch
                }
                //没有,按普通逻辑执行
                mHadExitAnim = true
                toMainActivity()
            }
        } else {
            toMainActivity()
        }
    }

    private fun toMainActivity() {
        Handler(Looper.getMainLooper()).postDelayed(Runnable {
            startActivity(Intent(this@SplashActivity, MainActivity::class.java))
        }, 3000)
    }

    /**
     * 是否需要启动闪屏页
     * */
    fun isNeedShowSplash(): Boolean {
        return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
    }

这里有个MainScope的delay(200),是用于适配一些国产系统rom阉割导致setOnExitAnimationListener没有回调的情况,不可缺少,否则部分机型不能进入下一个页面。

(二)使用原生进行适配
原生适配,思路和(一)大致一样。区别就是在于,不引入三方依赖进行适配了,仅仅在页面开始绘制的一瞬间,把系统的启动页面退出。核心代码如下:

    private var mHadExitAnim = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash2)

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            Log.d("Splash", "Splash 2 安卓12以上")
            splashScreen.setOnExitAnimationListener {
                Log.d("Splash", "Splash 2 setOnExitAnimationListener")
                it.remove()
                mHadExitAnim = true
                toMainActivity()
            }

            MainScope().launch {
                delay(200)
                if (mHadExitAnim) {
                    return@launch
                }
                //没有,按普通逻辑执行
                mHadExitAnim = true
                toMainActivity()
            }
        } else {
            Log.d("Splash", "Splash 2 安卓12以下")
            toMainActivity()
        }


    }

    private fun toMainActivity() {
        Handler(Looper.getMainLooper()).postDelayed(Runnable {
            startActivity(Intent(this@SplashActivityOnly, MainActivity::class.java))
        }, 3000)
    }

总结

目前比较常规的,就是这几种方法了。对于(一)方法,定制性高,不过就强制使用了系统的闪屏页了。对于(二),仅仅是减少系统闪屏页出现的时长。
以上就是适配启动页的一些思路。最后附上官方链接:
https://developer.android.google.cn/guide/topics/ui/splash-screen/migrate?hl=zh-cn

that’s all-------------------------------------------------------------------------------------------

猜你喜欢

转载自blog.csdn.net/motosheep/article/details/132908312