Android啓動頁解決攻略最終版

相信很多人都在網上查過關於啓動白屏或者黑屏的問題。

一般的App應該是分爲兩種:

  • 有閃屏頁或者啓動頁(SplashActivity),頁面大概會持續2到3秒
  • 沒有閃屏頁和啓動頁,打開應用後會直接跳轉到應用主界面

不管有沒有啓動頁,如果你不處理,你會發現當你點擊桌面上那個icon圖標的時候會先閃白屏或者黑屏一下,然後纔會進入我們設定的頁面。

但是我們手機上的常用應用,比如美團,今日頭條,微信等,點擊app icon的時候,其實感覺是一瞬間秒開的,沒有白屏的過程,那麼這是如何處理的呢?

先說一說爲什麼會出現白屏或者黑屏吧!

當打開一個Activity時,如果這個Activity所屬的應用還沒有在運行,系統會爲這個Activity所屬的應用創建一個進程,但進程的創建與初始化都需要時間,如果沒有任何反應的話,如果程序初始化的時間很長,用戶可能還以爲沒有點到相應的位置。但此時所啓動的程序還沒初始化完,既無法顯示程序,又不能停在原處不做任何動作,這就有了Starting Window的概念,也可以稱之爲Preview Window。

Starting Window就是一個用於在應用程序進程創建並初始化成功前顯示的臨時窗口,擁有的Window Type是TYPE_APPLICATION_STARTING。在程序初始化完成前顯示這個窗口,以告知用戶系統已經知道了他要打開這個應用並做出了響應,當程序初始化完成後顯示用戶UI並移除這個窗口。

顯示白屏或者黑屏,是由你的啓動Activity或者Application來決定的。如果你使用的是Light主題,那麼就可能出現白屏;如果你使用的是Black主題,那麼就可能出現黑屏。當你設置Light或者Black主題時,Starting Window顯示的就是你啓動Activity的android:windowBackground屬性,所以纔會出現白屏或者黑屏的情況。

網上有很多教程,說是把主題的背景設爲透明,這樣子的確實沒有白屏了,但是你會發現點擊完app的icon之後,會有一小會的停頓,給用戶一種卡頓的感覺,體驗非常不好,不能爲了實現功能而實現功能,軟件開發用戶體驗至上!


那麼好的體驗該如何開發呢?我們以實現一個今日頭條app的啓動頁作爲案例。

我們先來看一看常規情況下app啓動的黑白屏。

爲了讓白屏或者黑屏明顯的顯示,在SplashActivity的onCreate方法中setContentView之前加入一個休眠1秒的操作。

/*還沒有加載佈局是睡眠1秒,確保黑屏或白屏效果明顯*/
try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
/**閃屏頁持續1s然後進入主頁*/
mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(activity,AdsActivity.class);
                startActivity(intent);
                finish();
                overridePendingTransition(R.anim.fade,R.anim.hold);
            }
        }, 1000);

效果是:

沒做任何處理的啓動頁

接下來我們來消滅白屏。

第一步 消滅白屏

1.我們需要刪除原來的閃屏頁的佈局activity_splash.xml,同時刪除SplashActivity中setContentView(R.layout.activity_splash)方法。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    /*還沒有加載佈局是睡眠1秒,確保黑屏或白屏效果明顯*/
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

//    setContentView(R.layout.activity_splash);

}

2.爲了讓閃屏頁持續時間長一點,我們用handler模擬耗時操作,1秒後進行跳轉。

mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
        //這塊耗時操作可以進行初始化,或者網絡請求等,1秒結束後跳轉到廣告頁面
            Intent intent = new Intent(activity,AdsActivity.class);
            startActivity(intent);
            finish();
        }
    }, 1000);

3.我們刪除了閃屏頁的佈局文件,想法是將閃屏的背景作爲Activity的主題背景,要做到這一點,首先要在 res/drawable創建一個XML drawable文件。

<?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="20dp">
        <bitmap
            android:gravity="bottom"
            android:src="@mipmap/icon_logo" />
    </item>

</layer-list>

4.接下來在style.xml中創建一個閃屏頁的主題,將創建的xml設置爲window的背景。並且在AndroidManifest.xml中給SplashActivity配置style。

<style name="AppTheme.Splash" parent ="android:Theme.Holo.Light.NoActionBar">
    <item name="android:windowBackground">@drawable/drawable_splash</item>
</style>
<activity android:name=".SplahActivity"
       android:theme="@style/AppTheme.Splash">
       <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

這個時候運行程序,我們發現其實已經沒有白屏了。

第二步,我們實現廣告加載頁面

* 1.廣告頁是一個倒計時的顯示,佈局中放入一個TextView來顯示倒計時信息,放入一個ImageView來顯示加載動畫。點擊跳過廣告的時候顯示加載動畫。*

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/iv_logo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/icon_logo"
        android:layout_marginBottom="20dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"/>

    <RelativeLayout
        android:layout_marginBottom="20dp"
        android:layout_above="@+id/iv_logo"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorAccent">

        <TextView
            android:id="@+id/tv_ads"
            android:layout_alignParentRight="true"
            android:layout_marginTop="20dp"
            android:layout_marginRight="20dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="跳過廣告"
            android:textColor="@color/white"
            android:textSize="12sp"
            android:background="@drawable/bg_ad_text"
            android:padding="5dp"/>

    </RelativeLayout>

</RelativeLayout>

2.頁面實現中,我們定義一個CountDownTimer,這個類是Android SDK提供用來進行倒計時的。CountDownTimer(long millisInFuture, long countDownInterval)有兩個參數,第一個是計時的總時長,第二個是間隔。

public class AdsActivity extends Activity {
    private Activity activity;
    private TextView tvAds;
    private CountDownTimer countDownTimer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ads);
        activity =this;
        tvAds = (TextView) findViewById(R.id.tv_ads);

        countDownTimer = new CountDownTimer(4000,1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                tvAds.setText("跳過廣告"+(millisUntilFinished/1000)+"秒");
            }

            @Override
            public void onFinish() {
                Intent intent = new Intent(activity,MainActivity.class);
                startActivity(intent);
                finish();
            }
        }.start();

        /**
         * 跳過廣告
         */
        tvAds.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                countDownTimer.cancel();
                Intent intent = new Intent(activity,MainActivity.class);
                startActivity(intent);
                finish();
            }
        });
    }
}

第三步,優化

1.我們運行起來,發現頁面之間的跳轉有些不美觀,從右向左進入的動畫感覺有些生硬。因此我們給頁面之間加入轉場動畫。

#fade.xml 頁面退出動畫
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
       android:interpolator="@android:anim/accelerate_interpolator"
       android:fromAlpha="0.0" android:toAlpha="0.0"
       android:duration="400" />
#hold.xml 頁面進入動畫
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
       android:interpolator="@android:anim/accelerate_interpolator"
       android:fromXDelta="0" android:toXDelta="0"
       android:duration="400" />

在每個Intent跳轉的地方加入轉場效果

Intent intent = new Intent(activity,AdsActivity.class);
startActivity(intent);
finish();
overridePendingTransition(R.anim.fade,R.anim.hold);

最終的效果是:

消除黑白屏的啓動頁

有兩點注意:

  • overridePendingTransition方法要寫在finish後面
  • overridePendingTransition方法一定要寫在主線程中,在子線程是沒有作用的。

源碼地址:http://download.csdn.net/download/u012771445/9971093

本文作者: shijiacheng
本文鏈接:http://shijiacheng.studio/2017/09/09/android-splash-demo/
版權聲明:本博客所有文章除特別聲明外,均爲原創文章。請尊重勞動成果,轉載註明出處!
轉載請註明:轉自http://shijiacheng.studio

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章