🔥 Android 12 新功能
應用啟影片面 - Android 12 還為所有的應用帶來了新的啟影片面,應用也可以通過多種方式來定制啟影片面,以彰顯其獨有的品牌個性,
🔥 啟影片面
Android 12 添加了 SplashScreen API ,它可為所有應用啟用新的應用啟動影片,這包括啟動時的進入應用運動、顯示應用圖示的啟影片面,以及向應用本身的過渡,
默認情況下,使用啟動圖示,

🔥 啟影片面的作業原理
當用戶啟動應用而應用的行程未在運行(冷啟動)或 Activity 尚未創建(溫啟動)時,會發生以下事件,(在熱啟動期間從不顯示啟影片面,)
-
系統使用主題以及您已定義的任何影片顯示啟影片面,
-
當應用準備就緒時,會關閉啟影片面并顯示應用,
關于應用啟動模式可以參考:Android 性能優化之啟動優化,
🔥 影片的元素和機制
影片的元素由 Android 清單中的 XML 資源檔案定義,每個元素都有淺色模式和深色模式版本,
它們由視窗背景、影片形式的應用圖示和圖示背景組成:

關于這些元素,請注意以下幾點:
-
應用圖示 (1) 應該是矢量可繪制物件,它可以是靜態或影片形式,不超過 1000 毫秒,默認情況下,使用啟動圖示,
-
圖示背景 (2) 是可選的,在圖示與視窗背景之間需要更高的對比度時很有用,如果您使用一個自適應圖示,當該圖示與視窗背景之間的對比度足夠高時,就會顯示其背景,
-
與自適應圖示一樣,前景的三分之一被屏蔽(3),
-
視窗背景 (4) 由不透明的單色組成,如果視窗背景已設定且為純色,則未設定相應的屬性時默認使用該背景,
啟影片面影片機制由進入影片和退出影片組成,
-
進入影片由系統視圖到啟影片面組成,這由系統控制且不可自定義,
-
退出影片由隱藏啟影片面的影片運行組成,可以對其自定義,如果你要對其進行自定義,你將可以訪問 SplashScreenView 及其圖示,并且可以在它們之上運行任何影片(需要設定轉換、不透明度和顏色),在這種情況下,當影片完成時,需要手動移除啟影片面,
🔥 自定義應用中的啟影片面
💥 設定主題屬性以更改其外觀
🌀 設定啟影片面背景顏色
設定了淡紫色的背景圖,
效果圖:

代碼如下:
<style name="Theme.SccMall.SplashScreen">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowSplashScreenBackground">@color/splash_screen_background</item>
</style>
AndroidManifest.xml設定主題:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.SccMall.SplashScreen">
</application>
🌀 設定中間顯示的圖示
中心圖示大圖,內容需要保留2/3的內邊距,否則圖示會被裁剪掉,
設定透明的靜態圖示
圖示如下:

效果圖:

代碼如下:
<style name="Theme.SccMall.SplashScreen">
...
<item name="android:windowSplashScreenAnimatedIcon">drawable/iv_splash_animation1</item>
</style>
設定透明的動態圖示
效果圖:

代碼如下:
<style name="Theme.SccMall.SplashScreen">
...
<item name="android:windowSplashScreenAnimatedIcon">@drawable/splash_animate_icon</item>
<item name="android:windowSplashScreenAnimationDuration">1000</item>
</style>
splash_animate_icon.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/iv_1" android:duration="250"/>
<item android:drawable="@drawable/iv_2" android:duration="250"/>
<item android:drawable="@drawable/iv_3" android:duration="250"/>
<item android:drawable="@drawable/iv_4" android:duration="250"/>
</animation-list>
🌀 設定圖示的背景顏色
設定了紫色的圖示背景顏色,如果圖示背景不透明,會被遮擋效果無法看出,
效果圖:

代碼如下:
<style name="Theme.SccMall.SplashScreen">
...
<item name="android:windowSplashScreenIconBackgroundColor">@color/splash_screen_icon_background</item>
</style>
🌀 畫面底部的圖片(尺寸比例需要為 2.5:1,谷歌不推薦用)
效果圖:

這里使用的尺寸是500:200,
代碼如下:
<style name="Theme.SccMall.SplashScreen">
...
<item name="android:windowSplashScreenBrandingImage">@mipmap/iv_splash_screen_brandingimage</item>
</style>
💥 最終效果

效果:

代碼如下:
<style name="Theme.SccMall.SplashScreen">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<!-- 啟影片面背景顏色 -->
<item name="android:windowSplashScreenBackground">@color/splash_screen_background</item>
<!-- 啟影片面中間顯示的圖示,默認使用應用圖示 -->
<item name="android:windowSplashScreenAnimatedIcon">@drawable/iv_splash_animation1</item>
<!-- 啟影片面中間顯示的圖示的背景,如果圖示背景不透明則無效 -->
<item name="android:windowSplashScreenIconBackgroundColor">@color/splash_screen_icon_background</item>
<!-- 啟影片面啟影片面底部的圖片, -->
<item name="android:windowSplashScreenBrandingImage">@mipmap/iv_splash_screen_brandingimage</item>
<!-- 啟影片面在關閉之前顯示的時長,最長時間為 1000 毫秒, -->
<item name="android:windowSplashScreenAnimationDuration">1000</item>
</style>
💥 讓其在螢屏上顯示更長時間
啟影片面最長1000毫秒,如果你的廣告頁需要更多時間來加載資料,谷歌也提供了讓其顯示更長時間的方法,咱們一起來試試,
效果:

跟上面對比明顯發現時間延長了不少,
代碼如下:
public class AdvertiseActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
//延長啟影片面顯示時間
extendDisplayTime();
}
//延長啟影片面顯示時間
private void extendDisplayTime() {
MyViewModel myViewModel = new MyViewModel(getApplication());
// Set up an OnPreDrawListener to the root view.
final View content = findViewById(android.R.id.content);
content.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
// 檢查初始資料是否準備好,
if (myViewModel.isReady()) {
// 取消掛起,內容準備好了,
content.getViewTreeObserver().removeOnPreDrawListener(this);
return true;
} else {
// 掛起,內容未準備好,
return false;
}
//如果僅return false,則會產生一個永久顯示SplashScreen的效果,
}
});
}
public class MyViewModel extends AndroidViewModel {
public MyViewModel(Application application) {
super(application);
}
private long startUptimeMillis = SystemClock.uptimeMillis();
public boolean isReady(){
return SystemClock.uptimeMillis()-startUptimeMillis>3000;
}
}
}
💥 自定義用于關閉啟影片面的影片
效果:

代碼如下:
public class AdvertiseActivity extends AppCompatActivity {
ActivityAdvertiseBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
//關閉影片
spplashScreenCloseAnimation();
}
private void spplashScreenCloseAnimation(){
//添加一個回呼,當啟影片面為應用內容設定影片時呼叫,
getSplashScreen().setOnExitAnimationListener(splashScreenView -> {
final ObjectAnimator slideUp = ObjectAnimator.ofFloat(
splashScreenView,
View.TRANSLATION_Y,
0f,
-splashScreenView.getHeight()
);
slideUp.setInterpolator(new AnticipateInterpolator());
slideUp.setDuration(2000);
// 在自定義影片結束時呼叫splashScreenView.remove();
slideUp.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
//移除啟影片面
splashScreenView.remove();
}
});
// 啟動影片
slideUp.start();
});
}
}
🔥 低版本適配
效果(Android 5.1)

因為SplashScreen是在Android 12中才新增加的功能,所以在 Android 5.1 上面沒有效果,如果呼叫getSplashScreen()等 Android 12的新方法等會直接崩潰,
其實,有很多的App之前,就已經自己實作了SplashScreen功能,
那么自己實作的 SplashScreen 和官方提供的 SplashScreen 如何兼容? Android 12 是強制使用,如果不設定就使用默認應用圖示,所以,如果你的代碼中還保留著過去自己實作的那一套SplashScreen,在Android 12中就會出現雙重SplashScreen的現象,
因此這里可能就需要根據版本來做特殊處理了,要不就跟上面Demo一樣,先顯示一個SplashScreenView,后面跟個AdvertiseActivity(廣告界面?),
那如果去除自己的 AdvertiseActivity 低版本的要怎么辦?我們能想到的,谷歌大佬也能想到,
Google在AndroidX中提供了一個向下兼容的SplashScreen庫,根據官方的說法,我們只要使用這個庫就可以輕松解決舊版SplashScreen的適配問題,
💥 SplashScreen 庫
API 31 中引入的 SplashScreen API 的兼容類,
在 API 31+ (Android 12+) 上,此類呼叫平臺方法,
在 API 31 之前,平臺行為被復制,但啟動螢屏上的影片矢量可繪制支持除外,
要使用該類,需要將啟動Activity的主題設定為 R.style.Theme_SplashScreen 為其父級,并且需要設定 R.attr.windowSplashScreenAnimatedIcon 和 R.attr.postSplashScreenTheme 屬性,
也就是說這個庫是用來向下兼容,需要注意一下內容:
-
啟影片面的中心圖示影片(失效)
-
Activity的主題必須以 R.style.Theme_SplashScreen 為父級
-
從 API 23 開始兼容所有新 Splash Screen API,圖示背景除外,
💥 使用 SplashScreen 庫
🌀 匯入庫
最新版本
android {
compileSdkVersion 31
}
dependencies {
implementation 'androidx.core:core-splashscreen:1.0.0-alpha01'
}
🌀 設定主題
<style name="Theme.SccMall.Other">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
...
</style>
<style name="Theme.SccMall.SplashScreen" parent="Theme.SplashScreen">
<!-- 向下兼容, -->
<item name="windowSplashScreenBackground">@color/splash_screen_background</item>
<item name="windowSplashScreenAnimatedIcon">@drawable/iv_1</item>
<item name="postSplashScreenTheme">@style/Theme.SccMall.Other</item>
</style>
需要注意他們前面都沒有 android:,
windowSplashScreenBackground:啟影片面背景顏色,
windowSplashScreenAnimatedIcon:啟影片面中心的圖示,
postSplashScreenTheme:指定成你的App原來的主題,這樣,當SplashScreen結束時,你的主題就能夠被復原,從而不會影響到你的App的主題外觀,
🌀 設定AndroidManifest.xml
<application
...
android:theme="@style/Theme.SccMall.SplashScreen">
</application>
我這里就在原來的名字改,所以不用重設
🌀 Activity 中設定 SplashScreen
public class AdvertiseActivity extends AppCompatActivity {
ActivityAdvertiseBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SplashScreen.installSplashScreen(this);
binding = ActivityAdvertiseBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
binding.tvSplashJumpOver.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(AdvertiseActivity.this,"我要跳過",Toast.LENGTH_SHORT).show();
}
});
}
}
一定要加入到setContentView()的前面,
當然加入了你Android 12 功能還是不能使用(如延長啟影片面顯示時間等),
🌀 運行效果
Android 22(5.1.1)

就看到了背景色,連中心的圖示都沒生效,
Android 29(10)

背景顏色有了,中心圖示也出現了,主題也改回去了,
但是Android 12的部分功能丟失,
🌀 小結
-
Android SDK <23:中心圖示都沒有
-
23 < Android SDK <31 :中心圖示未進行切圓
-
Android SDK >=31 :新版本的方法無法使用
🔥 Android 5.0 - Android 12的兼容
💥 不進行處理,Android12 默認啟動短暫的啟影片面,
💥 在使用 SplashScreen 庫的基礎上修改
🌀 主題修改
針對 Android 31 新建一個values-v31里面放定制的Theme.SccMall.SplashScreen,

同時新增
<item name="postSplashScreenTheme">@style/Theme.SccMall.Other</item>
🌀 Activity修改
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SplashScreen.installSplashScreen(this);
binding = ActivityAdvertiseBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
...
//根據版本判斷是否使用此方法,
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
extendDisplayTime();
splashScreenCloseAnimation();
}
}
運行效果
Android 12:自定義應用中的啟影片面中有運行效果展示,
其他版本:使用 SplashScreen 庫的運行效果圖,
就不在這里粘圖浪費大家時間了,親測有效,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/347171.html
標籤:其他
