class MyFragment { public MyFragment(int title, String message){ } public static final MyFragment newInstance(int title, String message) { MyFragment f = new MyFragment (int title, String message); return f; } }
class MyFragment { private static final String TITLE="title",MESSAGE="message"; private String title,message; public void onCreate(Bundle saveInstanceState){ title = getArguments().getString(TITLE); message = getArguments().getString(MESSAGE); } public static final MyFragment newInstance(int title, String message) { MyFragment f = new MyFragment (int title, String message); Bundle bdl = new Bundle(2); bdl.setString(TITLE,title); bdl.setString(MESSAGE,message); f.setArguments(bdl); return f; } }
通過這種方式創建的Fragment在橫豎屏切換時通過getArguments依然能夠獲得之前設置的數據,其原理是在FragmentActivity切換時會調用onRetainNonConfigurationInstance方法將FragmentManager中管理的所有Fragment及其狀態數據(其中就包括了這個設置的Bundle)保存在一個FragmentActivity.NonConfigurationInstances對象實例中,這樣在新的FragmentActivity啟動時在onCreate方法中可以使用Activity.getLastNonConfigurationInstance()方法來獲取這個對象,然后通過FragmentManager.restoreAllState方法還原所有Fragment及其狀態,需要注意的是在這種情況下可能會出現之前的Fragment沒有detach而處於活動狀態導致該Fragment的視圖生成,可能會造成兩個Fragment視圖重疊的情況,在官方的Support.v4的例子中FragmentTabs.TabManager.addTab里有一段檢查Fragment是否detach的代碼正是用於解決這個問題。
通過上面的處理基本是沒問題了,但因為默認情況下橫豎屏切換后整個FragmentActivity會被銷毀並重建,所有Fragment中的成員變量也會丟失,但所有的Fragment狀態數據如上所述會被保留並還原,這個時候所有的視圖都會重新創建。
解決方法一:在相應的Activity配置中加上android:configChanges="orientation|keyboardHidden"設置,這樣切換時就不會銷毀FragmentActivity,所有的Fragment的狀態及視圖也就會保持。
解決方法二:在使用FragmentTransaction.add()方法添加fragment時設置第三個tag參數,隨后在還原時可通過FragmentManager.findFragmentByTag()方法找回還原的fragment.