App應用之啟動介面SplashActivity
當前比較成熟一點的應用基本上都會在進入應用之顯示一個啟動介面.
這個啟動介面或簡單,或複雜,或簡陋,或華麗,用意不同,風格也不同.
下面來觀摩幾個流行的應用的啟動介面.
1. 貨比三家
以騰訊qq,新浪weibo,UC瀏覽器,遊戲神廟逃亡等7個應用為例,比比看:
(我認為最精美的介面應該是qq2012,雖然只有一張圖,基本的應用名稱,版本,圖示這些資訊都有,但是看著舒服,覺得美.)
2. 元素
啟動介面的本意是以友好使用者介面來掩飾後臺緩衝載入,讓使用者用平和等待的心情進入正常應用介面.
但是因為啟動介面是放在開始,在這個特殊的點上,可以做更多的事情,如應用宣傳,顯示版權,展示廣告等等.
所以,這個啟動介面的元素,可多可少,就看你的用意和需求.
下面我把一些常見的元素羅列出來:
(1). 應用名稱
(2). 應用版本
(3). 應用圖示
(4). 版權
(5). 一句話描述
(6). 進度條
(7). 額外資訊,如市場專版,獨家首發等
... ...
3. 優點
啟動介面綜合考慮,至少有這些優點可以利用:
(1). 友好的等待介面,這是最基本的
(2). 應用的基本說明,宣傳介紹
(3). 動態的廣告,全屏廣告
(4). 應用的屬性說明如版本,版權等資訊,知曉使用者當前應用的基本屬性
從技術的角度細看,還有如下:
(5). 載入耗時資源
(6). 檢查新版本
(7). 預設條件
(8). 程式碼分離
... ...
4. 佈局
把能加的元素都加進去,做一個無設計的啟動介面,佈局如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> <TextView android:id="@+id/copy_right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="12dip" android:layout_centerHorizontal="true" android:layout_alignParentBottom="true" android:text="by xxxxx 出品" android:textSize="11sp"/> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:layout_centerInParent="true"> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal"> <ImageView android:id="@+id/jay_studio_icon" android:layout_width="110dip" android:layout_height="130dip" android:src="@drawable/app_jay"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/jay_studio_icon" android:src="@drawable/icon"/> </RelativeLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal"> <TextView android:id="@+id/app_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="6dip" android:text="@string/app_name" android:textSize="24sp"/> <TextView android:id="@+id/version_name" android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="bottom" android:paddingBottom="6dip" android:textSize="14sp"/> </LinearLayout> <View android:layout_width="fill_parent" android:layout_height="1px" android:layout_marginLeft="20dip" android:layout_marginRight="20dip" android:background="#dddddd"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:padding="6dip" android:text="@string/setting_about_description" android:textSize="13sp"/> <ProgressBar android:id="@+id/refresh_list_footer_progressbar" android:layout_width="24dip" android:layout_height="24dip" android:indeterminateDrawable="@anim/app_refresh_progress" android:layout_gravity="center"> </ProgressBar> </LinearLayout> </RelativeLayout> </RelativeLayout>
這個佈局僅表示意,效果如下:
5. 程式碼分離
專門拿這一點出來強調,是為了增強寫程式的程式碼分離意識,減少雜糅.
比如說檢查新版本這個操作,
如果放在主介面中,就容易把本來是一個獨立的操作和載入資料的操作混在一起,增加了主介面程式碼的複雜度,
如果放啟動介面中,就會顯得更乾淨更清晰的在啟動模組中檢測(因為檢測新版本本來就是應該在應用啟動的時候執行),而且還可以考慮是否允許使用者進入主介面(當你決定完全放棄老版本的時候,有時需要強制使用者升級到新版本)。
其他的一些操作,通過如此考慮,也可能會優化到程式碼結構。
6. 非同步執行任務
在啟動介面友好展示的同時,後臺可以做很多操作,這些後臺操作可以使用AsyncTask來最簡單的實現。
其他的方法也可以,但是我覺得這時候AsyncTask最簡潔了,這個時候不用AsyncTask什麼時候用AsyncTask。
public class SplashActivity extends BaseActivity {
private static final int FAILURE = 0; // 失敗
private static final int SUCCESS = 1; // 成功
private static final int OFFLINE = 2; // 如果支援離線閱讀,進入離線模式
private TextView mVersionNameText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
mVersionNameText = (TextView) findViewById(R.id.version_name);
mVersionNameText.setText(BaseApplication.mVersionName);
... ...
new AsyncTask<Void, Void, Integer>() {
@Override
protected Integer doInBackground(Void... params) {
int result;
... ...
result = loadingCache();
... ...
return result;
}
@Override
protected void onPostExecute(Integer result) {
};
}.execute(new Void[]{});
}
private int loadingCache() {
if (BaseApplication.mNetWorkState == NetworkUtils.NETWORN_NONE) {
return OFFLINE;
}
... ...
return SUCCESS;
}
}
把後臺的操作全部放到doInBackground方法中去,最後返回三種狀態,作為後臺執行的結果.
7. 跳轉動畫
在onPostExecute方法中,我們一定會最終要跳轉到另外一個activity,並且把自己finish掉的。
這個跳轉的動畫,在我的手機預設是左右滑進滑出的,其實這個動畫是可以自定義的,比如使用淡入淡出的跳轉動畫。
首先,定義淡入淡出的兩個動畫fade_in.xml和fade_out.xml放到res/anim資料夾中:
<!--fade_in.xml-->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<alpha
android:fromAlpha="0"
android:toAlpha="1"
android:duration="500" />
</set>
<!--fade_out.xml-->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<alpha
android:fromAlpha="1"
android:toAlpha="0"
android:duration="500" />
</set>
然後,在finish之後呼叫overridePendingTransition方法使用上面的動畫檔案:
@Override
protected void onPostExecute(Integer result) {
// ... ...
Intent intent = new Intent();
intent.setClassName(SplashActivity.this, getString(R.string.splash_out_activity));
startActivity(intent);
finish();
//兩個引數分別表示進入的動畫,退出的動畫
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
};
8. 最短顯示時間
在實際工作中,發現一個小問題,有可能這個後臺操作用時很短,這樣直接跳轉的話,太快導致有一種閃一下的感覺,所以我們需要定義一個最短顯示時間,取值800ms.
private static final int SHOW_TIME_MIN = 800;
// ... ...
{
@Override
protected Integer doInBackground(Void... params) {
int result;
long startTime = System.currentTimeMillis();
result = loadingCache();
long loadingTime = System.currentTimeMillis() - startTime;
if (loadingTime < SHOW_TIME_MIN) {
try {
Thread.sleep(SHOW_TIME_MIN - loadingTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return result;
}
}
這樣跳轉的時候,就永遠不會有閃的感覺,但是800ms又是很短的一個時間,不會對使用者體驗造成干擾.
9. 小結
啟動介面是一個比較簡單的話題,針對一些碰到的問題,本文做了一個小小的整理,以作記錄.
轉載自:http://www.cnblogs.com/qianxudetianxia/archive/2012/12/30/2839700.html