說明:這篇文章主要解決android啟動頁圖片全屏時圖片被拉伸問題
需求:
最近app全面改版,然后啟動頁換成了一整張圖片,效果圖如下:
2、問題
剛開始的時候,切的是一整張圖,然后在兩部測試機下測試發現,啟動的時候:
①、底部的字體有稍微的變形;
②、圖片垂直方向有些許的壓縮【這個問題在改版之前有,測試沒有提這個問題,但是在這次改版的時候,想要進一步優化一下,啟動時感覺是兩張圖片的這種體驗不是很好】;
3、解決
(需要注意的是,啟動頁的圖片尺寸大小的選擇也是很影響到不同手機的適配的,目前我選擇的圖片的尺寸大小是1125 × 1884大小的,放在mipmap-xxhdpi文件夾下的,這個尺寸在目前公司測試機上適配都是OK的)
問題①解決方法:
下半部分字體為了防止變形,讓設計把效果圖切成了兩部分,上面圖片部分和下面的純文字部分,切圖如下:
更進一步優化的話,可以對圖片進行.9的適配
問題②解決方法:
圖片被壓縮,經過多次測試發現,是因為在Activity里面設置了沉浸式效果,導致圖片沒有全屏展示,在代碼中去掉了沉浸式效果,然后在styles.xml里對啟動頁進行主題設置,使布局占據狀態欄空間
清單文件代碼
<activity
android:name=".ui.other.SplashActivity"
android:enabled="false"
android:alwaysRetainTaskState="true"
android:theme="@style/SplashTheme"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
主題文件代碼
<!--android9.0啟動頁全屏適配-->
<!--!!!注意,這里修改,記得同步values-v27里面的樣式文件-->
<style name="SplashTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item><!--目前這個屬性未知-->
<item name="android:windowIsTranslucent">false
</item><!--沉浸透明狀態欄 可選,窗口是否是半透明,設置狀態欄的效果,這個值也會影響狀態效果-->
<item name="android:windowDisablePreview">false
</item><!--冷啟動是用到的屬性,窗口不可見時的預覽圖,為true時點擊app圖標會慢一會-->
<item name="android:windowBackground">@drawable/layer_launch2</item><!--替換啟動白屏的圖片-->
<!--<item name="android:windowBackground">@mipmap/ic_splash_logo</item>--><!--替換啟動白屏的圖片-->
<!-- 在5.0后,增加了一個windowDrawsSystemBarBackgrounds屬性,用來標志此窗口是否負責繪制系統欄背景,
我們把它設成false,這樣當它繪制windowBackground的時候,就會在NavigationBar之上。-->
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowTranslucentStatus">true</item><!--這行代碼使布局占據狀態欄空間-->
</style>
然后適配一下android8.0【對應api版本27】以上的機型,創建values-27文件夾,然后在該文件夾下創建styles.xml文件
values-27文件夾下styles.xml代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--android9.0啟動頁全屏適配-->
<style name="SplashTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowIsTranslucent">false
</item><!--沉浸透明狀態欄 可選,窗口是否是半透明,設置狀態欄的效果,這個值也會影響狀態效果-->
<item name="android:windowDisablePreview">false
</item><!--冷啟動是用到的屬性,窗口不可見時的預覽圖,為true時點擊app圖標會慢一會-->
<item name="android:windowBackground">@drawable/layer_launch2</item><!--替換啟動白屏的圖片-->
<!-- <item name="android:windowBackground">@mipmap/ic_splash_logo</item>--><!--替換啟動白屏的圖片-->
<!-- Android P 異性屏適配 可以達到全面屏的效果 -->
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<!-- 在5.0后,增加了一個windowDrawsSystemBarBackgrounds屬性,用來標志此窗口是否負責繪制系統欄背景,
我們把它設成false,這樣當它繪制windowBackground的時候,就會在NavigationBar之上。-->
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowTranslucentStatus">true</item><!--這行代碼使布局占據狀態欄空間-->
</style>
</resources>
該文件加了一行代碼,對android凹凸屏進行了適配
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
Google對劉海屏的顯示方式提供了三種顯示模式
// 默認情況,全屏頁面不可用劉海區域,非全屏頁面可以進行使用
public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT = 0;
// 允許頁面延伸到劉海區域
public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES = 1;
// 不允許使用劉海區域
public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER = 2;
在主題中加入android:windowLayoutInDisplayCutoutMode屬性指定顯示模式
冷啟動時為了防止出現白屏或者等待時間,加入了一張默認的圖片【也就是啟動頁的圖片】
<item name="android:windowBackground">@drawable/layer_launch2</item><!--替換啟動白屏的圖片-->
再看看SplashActivity布局文件里,啟動頁圖片的配置
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/layer_launch2"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
可以發現,其實app啟動時是有兩張圖片,一張冷啟動時的友好圖片,一張是真正的啟動頁的圖片,如果適配的不好的話,冷啟動時的背景圖就不會和SplashActivity的圖片完美重疊,也就是會出現圖片壓縮或者明顯感覺是兩張圖片放上去的效果。當然,因為我們現在app里面沒有加入廣告位,所以SplashActivity里面的ImageView用的是默認圖,如果用網絡請求的廣告圖,那么就不會有重疊的問題,即使這樣,冷啟動的圖片也要做好全屏適配的效果,回過頭來,還是先看目前的問題,圖片拉伸的問題
一是要對android P以上的手機進行劉海屏的適配;
二是不要在Activity里對代碼進行沉浸式效果的設置;
三在drawable文件夾下,創建圖層列表layer-list圖片;
layer_launch2.xml代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/white" />
<!--因為使用最長圖做適配,所以這里不會有需要填充的地方,所以上面注釋掉-->
<item android:bottom="150dp">
<bitmap
android:src="@mipmap/ic_splash_logo" />
</item>
<item android:bottom="30dp">
<bitmap
android:gravity="bottom|center"
android:src="@mipmap/ic_splash_bottom" />
</item>
</layer-list>
對應的效果圖如下
可以發現,其實是第一層是白色背景,第二層是上半部分切圖,設置了距離底部150dp,150dp是留出來顯示底部問題的高度,這個大小可以自己設置,第三層設置的是圖片底部居中,然后距離底部30dp,通過三層疊加的效果,實現了最終的效果圖,一般的啟動頁的圖片都是通過這種圖層列表來實現,這樣適配的效果會更好一些
至此,android啟動頁圖片全屏時圖片被拉伸問題的問題解決掉啦!
4、總結
作為一名有職業道德的程序員,對於代碼中的瑕疵還是要解決的,特別是對於啟動頁這種“門面”,啟動頁的代碼處理邏輯其實就這幾個方面:切圖尺寸選擇、主題文件配置【劉海屏適配】、drawable文件創建及處理、、沉浸式效果處理。