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兩個方法。
@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方法來做更進一步的處理。例如官方範例:
@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开发教程及【亲测】Activity中的 ConfigChanges 属性以及横竖屏切换时候 Activity 的生命周期 @ 漫步云端這兩篇文章中的Lifecycle感覺有點奇怪,於是自己測了一下,所得到的結果似乎不太一樣,可能是模擬器的行為跟手機的不同,也有可能是Android版本不同(小蛙是用HTC Desire + MIUI2.3測試的,android:minSdkVersion=”4″),以下是測試結果供參考。
// 正常啟動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() 函式 @ 我思故我在