Android Screen Orientation Event螢幕方向處理+Acitivity Liftcycle
前幾篇文章中介紹了 使用Activity取代TabActivity 以及 透過ActivityGroup達到TabHost中切換Activity。之後會再補上使用 FragmentActivity + Fragment + TabHost 的作法 (Google 建議使用 Fragment)。這篇文章小蛙要記錄當使用者螢幕方向改變時的處理方式。
在發表完上面兩篇文章後,小蛙馬上實作看看使用 FragmentActivity 的方法,實作上面跟 ActivityGroup 差不多,勝過 ActivityGroup 的部分在於有自動維護的 BackStack,不用再自行建立 ArrayList<View> history 來管理 BackStack。至於為什麼沒有馬上發表文章呢?是因為小蛙想要把螢幕方向這件事情一起處理掉再發表,目前的情況是這樣的:
問題1.
使用者在 portrait 時切換到 Tab 2,翻轉螢幕成 landscape 時卻回到 Tab 1 (應該要停在 Tab 2)。
問題2.
軟體啟動時為 portrait(A),使用者在 Tab 1 先後運行了 Page1-1、Page1-2、Page1-3,在 Tab2 也同樣運行了 Page2-1 ~ Page2-4,這時候使用者翻轉螢幕變成landscape(B),BackStack 全部被清光光,使用者看到的畫面變成軟體剛啟動時的空白畫面。
針對問題1小蛙直接使用 onSaveInstanceState, onRestoreInstanceState使用 這個方法複寫了 onRestoreInstanceState 及 onSaveInstanceState 兩個方法。
01
02
03
04
05
06
07
08
09
10
11
12
13
|
@Override protected void onSaveInstanceState(Bundle outState) { // 發生翻轉動作的時候將目前頁籤儲存到Bundle中 outState.putInt( "which" , tabHost.getCurrentTab()); super .onSaveInstanceState(outState); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { // 把剛剛存的取出來 if (savedInstanceState != null ) tabHost.setCurrentTab(savedInstanceState.getInt( "which" )); super .onRestoreInstanceState(savedInstanceState); } |
但是今天發現了一個新的東西叫作「android:configChanges
」,這應該算是一個蠻基礎的設定,小蛙真是太失敗了…下面這個設定方法可以一併解決上述問題 1,2,也就是說上面的方法不需要用到。用小蛙簡單白話的說明就是:
當使用者翻轉螢幕時,就歷經了一次舊 Activity 的死亡及新 Activity 的誕生,透過 android:configChanges 可以使得翻轉螢幕的動作不用歷經這一個過程,取而代之的是呼叫 onConfigurationChanged 方法。
好吧!總而言之就是只要在 AndroidManifest.xml 的 Activity 敘述中加入android:configChanges=”orientation”,如此一來,當發生螢幕翻轉事件的時候,就可以保留各個 Tab 的狀態以及 BackStack 囉!另外可以透過複寫 onConfigurationChanged 方法來做更進一步的處理。例如官方範例:
01
02
03
04
05
06
07
08
09
10
|
@Override public void onConfigurationChanged(Configuration newConfig) { super .onConfigurationChanged(newConfig); // Checks the orientation of the screen if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { Toast.makeText( this , "landscape" , Toast.LENGTH_SHORT).show(); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ Toast.makeText( this , "portrait" , Toast.LENGTH_SHORT).show(); } } |
附上 Android Activity Lifecycle 圖 (圖片來源:http://developer.android.com/reference/android/app/Activity.html)。
由於小蛙看到 横竖屏切换时候Activity的生命周期 @ Android开发教程 ( http://android.tgbus.com/Android/tutorial/201103/346550.shtml 連結已失效) 及 【亲测】Activity中的 ConfigChanges 属性以及横竖屏切换时候 Activity 的生命周期 @ 漫步云端 (http://www.cnblogs.com/charley_yang/archive/2011/04/17/2018940.html 連結已失效) 這兩篇文章中的 Lifecycle 感覺有點奇怪,於是自己測了一下,所得到的結果似乎不太一樣,可能是模擬器的行為跟手機的不同,也有可能是 Android 版本不同 (小蛙是用 HTC Desire + MIUI2.3 測試的,android:minSdkVersion=”4″),以下是測試結果供參考。
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
// 正常啟動Activity onCreate onStart onResume // 結束Activity onPause onStop onDestroy // 翻轉螢幕(直轉橫、橫轉直) onSaveInstanceState onPause onStop onDestroy onCreate onStart onRestoreInstanceState onResume // 翻轉螢幕(直轉橫、橫轉直) // 以及android:configChanges="orientation" onConfigurationChanged |
今天用模擬器測試了一下,android:configChanges=”orientation” 在模擬器上沒法正常使用,必須要改成 android:configChanges=”orientation|keyboardHidden”,有遇到問題的網友不妨試試看。
最後memo一下,小蛙在官網連結中看到 onRetainNonConfigurationInstance 這個東西,查了三篇文章大概看了一下內容看起來應該蠻實用的,之後有空實作完再把結果Post上來。
[Android] 煩人的螢幕旋轉 @ 生活藝術 ● 藝術生活
activity状态的保存和保持(onRetainNonConfigurationInstance和getLastNonConfigurationInstance) @ chengbs
[Android] 比較onSaveInstanceState() 與 onRetainNonConfigurationInstance() 函式 @ 我思故我在