Android啟動頁解決攻略最終版

相信很多人都在網(wǎng)上查過關(guān)于啟動白屏或者黑屏的問題竖慧。

一般的App應(yīng)該是分為兩種:

  • 有閃屏頁或者啟動頁(SplashActivity),頁面大概會持續(xù)2到3秒
  • 沒有閃屏頁和啟動頁颓哮,打開應(yīng)用后會直接跳轉(zhuǎn)到應(yīng)用主界面

不管有沒有啟動頁,如果你不處理不从,你會發(fā)現(xiàn)當(dāng)你點擊桌面上那個icon圖標(biāo)的時候會先閃白屏或者黑屏一下藻丢,然后才會進(jìn)入我們設(shè)定的頁面。

但是我們手機上的常用應(yīng)用杨帽,比如美團(tuán)漓穿,今日頭條,微信等注盈,點擊app icon的時候晃危,其實感覺是一瞬間秒開的,沒有白屏的過程老客,那么這是如何處理的呢僚饭?

先說一說為什么會出現(xiàn)白屏或者黑屏吧!

當(dāng)打開一個Activity時胧砰,如果這個Activity所屬的應(yīng)用還沒有在運行鳍鸵,系統(tǒng)會為這個Activity所屬的應(yīng)用創(chuàng)建一個進(jìn)程,但進(jìn)程的創(chuàng)建與初始化都需要時間尉间,如果沒有任何反應(yīng)的話偿乖,如果程序初始化的時間很長击罪,用戶可能還以為沒有點到相應(yīng)的位置。但此時所啟動的程序還沒初始化完汹想,既無法顯示程序外邓,又不能停在原處不做任何動作撤蚊,這就有了Starting Window的概念古掏,也可以稱之為Preview Window。

Starting Window就是一個用于在應(yīng)用程序進(jìn)程創(chuàng)建并初始化成功前顯示的臨時窗口侦啸,擁有的Window Type是TYPE_APPLICATION_STARTING槽唾。在程序初始化完成前顯示這個窗口,以告知用戶系統(tǒng)已經(jīng)知道了他要打開這個應(yīng)用并做出了響應(yīng)光涂,當(dāng)程序初始化完成后顯示用戶UI并移除這個窗口庞萍。

顯示白屏或者黑屏,是由你的啟動Activity或者Application來決定的忘闻。如果你使用的是Light主題钝计,那么就可能出現(xiàn)白屏;如果你使用的是Black主題齐佳,那么就可能出現(xiàn)黑屏私恬。當(dāng)你設(shè)置Light或者Black主題時,Starting Window顯示的就是你啟動Activity的android:windowBackground屬性炼吴,所以才會出現(xiàn)白屏或者黑屏的情況本鸣。

網(wǎng)上有很多教程,說是把主題的背景設(shè)為透明硅蹦,這樣子的確實沒有白屏了荣德,但是你會發(fā)現(xiàn)點擊完app的icon之后,會有一小會的停頓童芹,給用戶一種卡頓的感覺涮瞻,體驗非常不好,不能為了實現(xiàn)功能而實現(xiàn)功能假褪,軟件開發(fā)用戶體驗至上署咽!


那么好的體驗該如何開發(fā)呢?我們以實現(xiàn)一個今日頭條app的啟動頁作為案例嗜价。

我們先來看一看常規(guī)情況下app啟動的黑白屏艇抠。

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

/*還沒有加載布局是睡眠1秒家淤,確保黑屏或白屏效果明顯*/
try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
/**閃屏頁持續(xù)1s然后進(jìn)入主頁*/
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.為了讓閃屏頁持續(xù)時間長一點,我們用handler模擬耗時操作青伤,1秒后進(jìn)行跳轉(zhuǎn)督怜。

mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
        //這塊耗時操作可以進(jìn)行初始化,或者網(wǎng)絡(luò)請求等狠角,1秒結(jié)束后跳轉(zhuǎn)到廣告頁面
            Intent intent = new Intent(activity,AdsActivity.class);
            startActivity(intent);
            finish();
        }
    }, 1000);

3.我們刪除了閃屏頁的布局文件号杠,想法是將閃屏的背景作為Activity的主題背景,要做到這一點丰歌,首先要在 res/drawable創(chuàng)建一個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中創(chuàng)建一個閃屏頁的主題,將創(chuàng)建的xml設(shè)置為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>

這個時候運行程序,我們發(fā)現(xiàn)其實已經(jīng)沒有白屏了晓勇。

第二步堂飞,我們實現(xiàn)廣告加載頁面

** 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.頁面實現(xiàn)中羡玛,我們定義一個CountDownTimer别智,這個類是Android SDK提供用來進(jìn)行倒計時的。CountDownTimer(long millisInFuture, long countDownInterval)有兩個參數(shù)稼稿,第一個是計時的總時長薄榛,第二個是間隔。

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();
            }
        });
    }
}

第三步让歼,優(yōu)化

1.我們運行起來敞恋,發(fā)現(xiàn)頁面之間的跳轉(zhuǎn)有些不美觀,從右向左進(jìn)入的動畫感覺有些生硬谋右。因此我們給頁面之間加入轉(zhuǎn)場動畫硬猫。

#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 頁面進(jìn)入動畫
<?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跳轉(zhuǎn)的地方加入轉(zhuǎn)場效果

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/
版權(quán)聲明:本博客所有文章除特別聲明外啸蜜,均為原創(chuàng)文章。請尊重勞動成果辈挂,轉(zhuǎn)載注明出處衬横!
轉(zhuǎn)載請注明:轉(zhuǎn)自http://shijiacheng.studio

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市终蒂,隨后出現(xiàn)的幾起案子蜂林,更是在濱河造成了極大的恐慌遥诉,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件噪叙,死亡現(xiàn)場離奇詭異矮锈,居然都是意外死亡,警方通過查閱死者的電腦和手機睁蕾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門苞笨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人惫霸,你說我怎么就攤上這事猫缭〈械埽” “怎么了壹店?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長芝加。 經(jīng)常有香客問我硅卢,道長,這世上最難降的妖魔是什么藏杖? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任将塑,我火速辦了婚禮,結(jié)果婚禮上蝌麸,老公的妹妹穿的比我還像新娘点寥。我一直安慰自己,他們只是感情好来吩,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布敢辩。 她就那樣靜靜地躺著,像睡著了一般弟疆。 火紅的嫁衣襯著肌膚如雪戚长。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天怠苔,我揣著相機與錄音同廉,去河邊找鬼。 笑死柑司,一個胖子當(dāng)著我的面吹牛迫肖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播攒驰,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蟆湖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了讼育?” 一聲冷哼從身側(cè)響起帐姻,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤稠集,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后饥瓷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體剥纷,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年呢铆,在試婚紗的時候發(fā)現(xiàn)自己被綠了晦鞋。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡棺克,死狀恐怖悠垛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情娜谊,我是刑警寧澤确买,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站纱皆,受9級特大地震影響湾趾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜派草,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一搀缠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧近迁,春花似錦艺普、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至拓瞪,卻和暖如春缴罗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背祭埂。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工面氓, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蛆橡。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓舌界,卻偏偏與公主長得像,于是被迫代替她去往敵國和親泰演。 傳聞我的和親對象是個殘疾皇子呻拌,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容