Android SplashScreen API:打造引人注目的启动画面

在这里插入图片描述

前言

在移动应用开发中,启动画面是用户第一次接触到应用的重要组成部分,也是第一印象。然而,许多 Android 应用在启动阶段都面临着一个普遍的问题:白屏。为了改善这一问题,我们通常的做法都是自定义一个单独的启动页面,但这并没有解决根本问题。

于是谷歌在 Android 12 系统上引入 SplashScreen API,它可以让开发者轻松的添加应用画面,开发者只需要添加我们的应用图标以及定义动画的进出场,便可解决白屏问题。

SplashScreen

虽然 SplashScreen 的登场解决了白屏问题,但是它仅支持 Android 12及以上版本,但是在 12 以下的手机系统还占有着很大一部分,于是乎 Core SplashScreen 出现了,它属于 Jetpack 组件中的一员,用于适配低版本的手机系统。

工作原理

首先应用的启动情况分为三种情况:冷启动、温启动、热启动。

  • 冷启动:当首次启动或者应用被系统杀死之后应用就属于冷启动,这时会显示我们定义的启动画面。
  • 温启动:应用已经创建,但是 activity 已经被销毁了,这是启动应用它会重新创建 activity 这属于温启动,由于 activity 销毁重建所以它也是会显示启动画面。
  • 热启动:当应用已经创建并且用户点击 Home 键后应用会进入系统后台这时再次启动就属于热启动,此时不会再显示启动画面。

示例

1.添加依赖

首先在模块级别的 build.gradle 文件中引入依赖。

implementation "androidx.core:core-splashscreen:1.0.1"

2.添加及配置元素

为了给图标添加动画效果,官方提供了两种选项,这里使用第二种 AnimatedVectorDrawable,该选项可以为尺量对象的属性添加动画效果。
官方文档
您通常在三个 XML 文件中定义添加动画效果之后的矢量可绘制对象:

  • 一个矢量可绘制对象, 元素位于 res/drawable 目录下。
  • 一个添加动画的矢量可绘制对象, 位于 res/drawable 目录下。
  • 一个或多个对象 Animator, 位于 res/animator 目录下。

添加我们的应用图标,这里我直接从官方资源 Vector Asset 中随便引入一个,重命名替换为 logo ,尺寸方面我选择的是 50x50。
在这里插入图片描述
启动页面的图标可以是静态或者动态,这里以简单的旋转缩放动画为例,当应用启动时,图标从中心点开始旋转 360° 并且从 0.0 缩放到 0.4。

使用 定义一组路径,注意有些图标的绘制是不止一条 ,所以把所有 路径包裹起来作为一个整体组,否则就会出现某一部分脱节无运动效果。然后添加一个组名称。

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="50dp"
    android:height="50dp"
    android:tint="#08FF04"
    android:viewportWidth="24"
    android:viewportHeight="24">

    <!--  整个logo设置为组  -->
    <group
        android:name="animationGroup"
        android:pivotX="12"
        android:pivotY="12">
      
      <!--  如果有多个Path,请全部包裹  -->
        <path
            android:fillColor="@android:color/white"
            android:pathData="M17.6,9.48l1.84,-3.18c0.16,-0.31 0.04,-0.69 -0.26,-0.85c-0.29,-0.15 -0.65,-0.06 -0.83,0.22l-1.88,3.24c-2.86,-1.21 -6.08,-1.21 -8.94,0L5.65,5.67c-0.19,-0.29 -0.58,-0.38 -0.87,-0.2C4.5,5.65 4.41,6.01 4.56,6.3L6.4,9.48C3.3,11.25 1.28,14.44 1,18h22C22.72,14.44 20.7,11.25 17.6,9.48zM7,15.25c-0.69,0 -1.25,-0.56 -1.25,-1.25c0,-0.69 0.56,-1.25 1.25,-1.25S8.25,13.31 8.25,14C8.25,14.69 7.69,15.25 7,15.25zM17,15.25c-0.69,0 -1.25,-0.56 -1.25,-1.25c0,-0.69 0.56,-1.25 1.25,-1.25s1.25,0.56 1.25,1.25C18.25,14.69 17.69,15.25 17,15.25z" />
    </group>

</vector>

创建 Animator 动画对象,通过属性给图标配置动画。
在这里插入图片描述
官方建议动画时长不要超过1000毫秒(1秒钟),代码中我设置了运行时长为1秒以及旋转和缩放动画,启动时图标从中心点 0° 旋转 360°,并且从 XY 轴从 0 倍缩放到 0.4 倍。

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000">
    <!-- 旋转动画 -->
    <propertyValuesHolder
        android:propertyName="rotation"
        android:valueFrom="0.0"
        android:valueTo="360.0"
        android:valueType="floatType" />
  
    <!-- X轴缩放动画 -->
    <propertyValuesHolder
        android:propertyName="scaleX"
        android:valueFrom="0.0"
        android:valueTo="0.4"
        android:valueType="floatType" />
  
    <!-- Y轴旋转动画 -->
    <propertyValuesHolder
        android:propertyName="scaleY"
        android:valueFrom="0.0"
        android:valueTo="0.4"
        android:valueType="floatType" />

</objectAnimator>

接下来图标和动画属性两个文件都有了,使用动画矢量把他们组合到一起即可,编译器右侧可以播放动画来预览我们设置的效果。

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/logo"><!-- 引用图标 -->

    <!-- 引用动画属性和设定的组 -->
    <target
        android:animation="@animator/logo_animator"
        android:name="animationGroup"/>

</animated-vector>

在这里插入图片描述

3.创建启动主题

在 values/theme.xml 文件中自定义启动主题,它用于替换掉 MainActivity 原有的默认主题并且在启动完成之后自动切换回我们默认的主题。注意:还需要创建一个 SDK-31的 theme.xml ,用于高版本。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- 默认主题 -->
    <style name="Theme.AnimationsSplashScreenApi" parent="android:Theme.Material.Light.NoActionBar" />

    <!-- 启动主题(低版本使用),高版本用的是 -v31 -->
    <style name="Theme.App.Starting" parent="Theme.SplashScreen">
        <item name="windowSplashScreenAnimatedIcon">@drawable/animated_logo</item>
        <item name="postSplashScreenTheme">@style/Theme.AnimationsSplashScreenApi</item>
    </style>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="Theme.App.Starting" parent="Theme.SplashScreen">
        <item name="android:windowSplashScreenAnimatedIcon">@drawable/animated_logo</item>
        <item name="postSplashScreenTheme">@style/Theme.AnimationsSplashScreenApi</item>
    </style>
</resources>

两者唯一的区别在于高版本使用的是带有 android: 的属性,低版本不具备动画效果,但是会显示固定的图标。
在这里插入图片描述

4.应用主题

在清单文件中给替换掉默认的应用程序主题和 MainActivity 主题。

<application
    ...
    android:theme="@style/Theme.App.Starting"
    tools:targetApi="31">
    <activity
       ...
        android:theme="@style/Theme.App.Starting">
       ...
    </activity>
</application>

5.installSplashScreen

在启动Activity时先调用installSplashScreen(),然后再调用 super.onCreate()。

class MainActivity : ComponentActivity() {

      override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            //安装启动页
            installSplashScreen()
            
            setContent {
                ...
            }
      }
}

到这里一个带有动画的启动页就弄好了,但是还不够结合实际情况,应用在启动时都会去网络或者本地加载数据,这期间用户进入到了首页而没有数据展示,就处于非常尴尬的局面,所以需要优化一下。

setKeepOnScreenCondition() 函数用于配置启动页停留的条件,比如当数据加载完成之后才进入主界面。

//创建ViewModel,模拟网络加载数据
class MainViewModel : ViewModel() {

      private val _isReady = mutableStateOf(false)
      val isReady: State<Boolean> = _isReady

      init {
            viewModelScope.launch {
                  delay(3000L)
                  _isReady.value = true
            }
      }
}

// MainActivity
class MainActivity : ComponentActivity() {

      private val viewModel by viewModels<MainViewModel>()

      override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)

            installSplashScreen().apply {
                  //设置停留在闪屏页上的条件
                  //当条件为false的时候会一直停留反之进入主界面
                  setKeepOnScreenCondition {
                        !viewModel.isReady.value
                  }
            }

            setContent {
                  ...
            }
      }
}

6.运行效果

在这里插入图片描述
迁移文档
官方文档

关注我,与你分享更多技术文章。麻烦右下角区域点个【赞】支持一下吧!更多内容请关注下方微信公众号。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值