前幾篇文章中介紹了使用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使用這個方法複寫了onRestoreInstanceStateonSaveInstanceState兩個方法。

@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() 函式 @ 我思故我在

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *