Android啟動頁實現(xiàn)(啟動優(yōu)化倦淀,劉海屏水滴屏全屏適配等)

最終效果圖

image

ps

這個圖片大小真的調不來吊输。。激率,如果太影響閱讀可移步至DemoREADME

前言

最近想實現(xiàn)一個啟動頁咳燕,于是試了手機里的幾個常用App,總結出以下需要實現(xiàn)要點注意點

  1. 啟動優(yōu)化

    一般情況下乒躺,冷啟動時在Application初始化的過程中會出現(xiàn)短暫的白屏或黑屏招盲,這里可以做一個優(yōu)化,提高用戶體驗嘉冒。
  2. 固定屏幕方向

    經測試曹货,大多數(shù)的應用(宇宙條除外),其啟動頁都是僅支持豎屏展示的讳推,如果橫屏展示的圖片會被拉伸顶籽,影響美觀。
  3. 開屏廣告 —— 異形屏全屏適配(劉海屏银觅,水滴屏等)

    通常啟動頁都會有一個開屏頁廣告礼饱,需要占據通知欄的,一般情況下只需要設置一個全屏主題即可解決究驴,但是當碰到異形屏(如 水滴屏镊绪,劉海屏等)時就需要做一些額外的適配工作。
  4. 虛擬的導航欄遮蓋問題

    如果存在虛擬NavigationBar纳胧,那么還需要做一個適配镰吆,否則默認情況下啟動頁的底部如果有文字或圖片的話會被虛擬的導航欄遮蓋住跑慕。
  5. 屏蔽Back鍵

    即展示啟動頁時back無效万皿,但是可以按home鍵返回桌面摧找。



ok,明白了需求牢硅,下面開始實際操作:

基本實現(xiàn)

首先我們先來實現(xiàn)一個基礎版本蹬耘,然后再一點一點的進行優(yōu)化
由于最近在學習架構組件减余,所以Demo是基于MVVM實現(xiàn)的综苔,不過對于本文的內容并沒有什么影響。

  1. 自定義定義全屏主題 AppTheme.Splash
<!--全屏主題-->
<style name="AppTheme.Splash" parent="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>
    <!-- 設置window過度效果 禁用窗口的預覽動畫 -->
    <item name="android:windowDisablePreview">false</item>
</style>
  1. 定義我們的啟動頁 SplashActivity 并在AndroidManifest.xml設置上自定義的全屏主題
public class SplashActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivitySplashBinding mBinding =
                DataBindingUtil.setContentView(this, R.layout.activity_splash);

        //2s延遲后進入MainActivity
        new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(SplashActivity.this, MainActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
                finish();
            }
        }, 2000);
    }
}
<activity 
    android:theme="@style/AppTheme.Splash"
    android:name=".splash.SplashActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
  1. layout文件就不上了位岔,通過效果圖就能看出來如筛,就只是放了一張圖片。

效果圖(Pixel):

image

可以看到有很明顯的白屏抒抬。

啟動優(yōu)化

這里的啟動優(yōu)化杨刨,其實是給啟動時的白屏添加一個背景,這樣用戶在使用時是無感知的擦剑,從來造成一種啟動很快的錯覺妖胀。

  1. drawable 文件夾下面制作背景圖片layer_launcher.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item>
        <shape android:shape="rectangle">
            <solid android:color="#FFF" />
        </shape>
    </item>

    <item android:bottom="25dp">
        <bitmap
            android:gravity="bottom|center_horizontal"
            android:src="@drawable/ic_launcher" />
    </item>
</layer-list>
  1. 全屏主題AppTheme.Splash設置上我們自定義的背景
<style name="AppTheme.Splash" parent="Theme.AppCompat.Light.NoActionBar">
    ...
    <!-- 設置window背景 -->
    <item name="android:windowBackground">@drawable/layer_launcher</item>
</style>
  1. 設置了window的背景之后,啟動頁就可以不設置圖片了
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
           
        <TextView
            android:gravity="center"
            android:text="splash activity"
            android:background="#F00"
            android:layout_marginBottom="120dp"
            android:layout_gravity="center_horizontal"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

        <!-- <View-->
        <!--    android:layout_width="match_parent"-->
        <!--    android:layout_height="0dp"-->
        <!--    android:layout_weight="1" />-->
        
        <!-- <ImageView-->
        <!--    android:layout_width="80dp"-->
        <!--    android:layout_height="80dp"-->
        <!--    android:layout_gravity="center_horizontal|bottom"-->
        <!--    android:layout_marginBottom="30dp"-->
        <!--    android:scaleType="fitXY"-->
        <!--    android:src="@drawable/ic_launcher" />-->

    </LinearLayout>
</layout>

效果圖(RedMi 3S):

image

ok惠勒,可以看到赚抡,設置了背景之后感覺好多了,只不過這里為了更好的辨別添加了一個大紅色的TextView可能看起來還是比較突兀纠屋。 = =

ps:

如果你的背景圖片被拉伸變形了涂臣,可以嘗試把圖片資源轉移到 drawable-xxhdpi 文件下。

固定屏幕方向 —— 強制豎屏

這個簡單巾遭,其實就是在AndroidManifest.xmlSplashActivity設置screenOrientation屬性為 portrait 即可肉康。

<activity
    android:name=".splash.SplashActivity"
    android:screenOrientation="portrait"
    android:theme="@style/AppTheme.Splash">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

異形屏全屏適配

首先我們先來看看當前所實現(xiàn)的代碼在水滴屏上的效果(XiaoMi CC9e):

image



可以看到,屏幕上方有一個小黑條灼舍,所以對于異型屏吼和,我們需要進行額外的適配,這些適配可以分為兩種

  • Android P(9.0)及以上的手機骑素,Google官方給我們提供了解決方案炫乓。
  • Android O(8.0)及以下的手機,由于這時沒有官方的適配方案献丑,所以只能根據具體的機型去查看相應廠商給我們提供的解決文檔了末捣。

Android P 適配

根據文檔,我們只需要在全屏主題中再添加一個windowLayoutInDisplayCutoutMode屬性并且值為 shortEdges 即可创橄,只不過由于是Android P才出的箩做,所以需要復制一份主題到values-v28/styles.xml中并設置上該屬性:

<!-- values-v28/styles.xml -->
<?xml version="1.0" encoding="utf-8"?>
<resources>
    
    ...
    
    <style name="AppTheme.Splash" parent="Theme.AppCompat.Light.NoActionBar">
       
       ...
       
       <!-- Android P 異性屏適配 可以達到全面屏的效果 -->
       <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
    </style>
</resources>

Android O 適配

很遺憾,設備資源有限妥畏,手上的真機只有一部紅米3S小米CC9e(水滴屏 Android Q)邦邦,完美的避開了這種情況安吁。 = =

不過我有在某個博客中(原諒我找不到了原博客鏈接了)看到了解決方案(未驗證),需要的小伙伴的可以順便驗證一下:

<activity
    android:name=".splash.SplashActivity"
    android:screenOrientation="portrait"
    android:theme="@style/AppTheme.Splash">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

    <!--允許繪制到oppo燃辖、vivo劉海屏機型的劉海區(qū)域 -->
    <meta-data
        android:name="android.max_aspect"
        android:value="2.2" />

    <!-- 允許繪制到華為劉海屏機型的劉海區(qū)域 -->
    <meta-data
        android:name="android.notch_support"
        android:value="true" />

    <!-- 允許繪制到小米劉海屏機型的劉海區(qū)域 -->
    <meta-data
        android:name="notch.config"
        android:value="portrait" />
</activity>

全屏適配

你以為這樣就真的OK了嗎鬼店? too young too simple !,先來上面的方案執(zhí)行后的效果(XiaoMi CC9e):

image

之前的小黑條變成白條了,說明我們前面做的適配是生效了的黔龟,但是我們的TextView并沒有延伸要屏幕頂部妇智,下面是解決方案:

在全屏主題中添加以下兩個屬性即可,注意這兩條屬性是API 21出來的氏身,所以需要新建values-v21/styles.xml巍棱,別忘了之前添加的values-v28/styles.xml中也要加上:

<!-- values-v21/styles.xml -->
<?xml version="1.0" encoding="utf-8"?>
<resources>
    
    ...

    <style name="AppTheme.Splash" parent="Theme.AppCompat.Light.NoActionBar">
            
        ...
        
        <!-- 設置statusBarColor 為透明-->
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
    
    </style>
</resources>

效果圖(XiaoMi CC9e):

image

被虛擬NavigationBar遮擋問題

先來看一下當前代碼在Pixel上的運行情況:

image



可以看到我們的logo被虛擬的導航欄遮蓋住了,這時候需要在全屏主題中添加以下屬性:

<style name="AppTheme.Splash" parent="Theme.AppCompat.Light.NoActionBar">
     
     ...
     
    <!-- 在5.0后观谦,增加了一個windowDrawsSystemBarBackgrounds屬性拉盾,用來標志此窗口是否負責繪制系統(tǒng)欄背景,
    我們把它設成false豁状,這樣當它繪制windowBackground的時候,就會在NavigationBar之上倒得。-->
    <item name="android:windowDrawsSystemBarBackgrounds">false</item>
</style>

同樣的泻红,需要在 values-v21values-v28 下的styles.xml都加上

效果圖(pixel):

image


屏蔽Back鍵

重寫SplashActivityonBackPressed 方法什么都不做即可:

public class SplashActivity extends AppCompatActivity {

    ...

    @Override
    public void onBackPressed() {
        //屏蔽back鍵
    }
}

最后

Demo鏈接

原來一個啟動頁就有這么多的東西在里面霞掺。谊路。

Demo中肯定還有沒有適配到的地方,如果發(fā)現(xiàn)文中哪里有錯或不足歡迎指正~菩彬。

參考文章

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市骗灶,隨后出現(xiàn)的幾起案子惨恭,更是在濱河造成了極大的恐慌,老刑警劉巖耙旦,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脱羡,死亡現(xiàn)場離奇詭異,居然都是意外死亡免都,警方通過查閱死者的電腦和手機锉罐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绕娘,“玉大人脓规,你說我怎么就攤上這事∠樟欤” “怎么了侨舆?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵升酣,是天一觀的道長。 經常有香客問我态罪,道長噩茄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任复颈,我火速辦了婚禮绩聘,結果婚禮上,老公的妹妹穿的比我還像新娘耗啦。我一直安慰自己凿菩,他們只是感情好,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布帜讲。 她就那樣靜靜地躺著衅谷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪似将。 梳的紋絲不亂的頭發(fā)上获黔,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機與錄音在验,去河邊找鬼玷氏。 笑死,一個胖子當著我的面吹牛腋舌,可吹牛的內容都是我干的盏触。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼块饺,長吁一口氣:“原來是場噩夢啊……” “哼赞辩!你這毒婦竟也來了?” 一聲冷哼從身側響起授艰,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤辨嗽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后想诅,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體召庞,經...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年来破,在試婚紗的時候發(fā)現(xiàn)自己被綠了篮灼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡徘禁,死狀恐怖诅诱,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情送朱,我是刑警寧澤娘荡,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布干旁,位于F島的核電站,受9級特大地震影響炮沐,放射性物質發(fā)生泄漏争群。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一大年、第九天 我趴在偏房一處隱蔽的房頂上張望换薄。 院中可真熱鬧,春花似錦翔试、人聲如沸轻要。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冲泥。三九已至,卻和暖如春壁涎,著一層夾襖步出監(jiān)牢的瞬間凡恍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工粹庞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留咳焚,地道東北人。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓庞溜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親碑定。 傳聞我的和親對象是個殘疾皇子流码,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353