相信很多人都在網上查過關於啓動白屏或者黑屏的問題。
一般的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