相信很多人都在網(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