2012-02-23 23 views
13

私は、独自の状態(選択されたボタンなど)を持つフラグメントを持っています。その状態は画面の回転で失われます。なぜ私のフラグメントonSaveInstanceState()が呼び出されていないのですか?

このフラグメントを含むアクティビティは、/ res/layout /にポートレイトレイアウトがあり、/ res/layout-land /にほとんど同じランドスケープレイアウトがあります。どちらのレイアウトはそうのようなフラグメントが含まれる:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
    <fragment 
     android:id="@+id/testFragment" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     class="au.com.x.y.TestFragment" /> 
...</LinearLayout> 

私がテストしてきたフラグメントのクラスがある:私は持ち込ま断片の事前3.0サポートパッケージを、使用してい

public class TestFragment extends android.support.v4.app.Fragment { 
    private static final String TAG = "TestFragment"; 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     Log.i(TAG, "onCreate(): " + 
       (savedInstanceState != null ? "NOT NULL" : "NULL")); 
    } 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
     Log.i(TAG, "onActivityCreated(): " + 
       (savedInstanceState != null ? "NOT NULL" : "NULL")); 
    } 
    public void onSaveInstanceState(Bundle state) { 
     super.onSaveInstanceState(state); 
     Log.i(TAG, "onSaveInstanceState()"); 
     state.putString("saved_thing", "some_value"); 
    } 
    public View onCreateView(
     LayoutInflater inflater, 
     ViewGroup container, 
     Bundle b) { ... } 
} 

注意ActionBarSherlockを介して。あなたが見ることができるように、onSaveInstanceState()が呼び出されることはありません

BEFORE SCREEN ROTATION (PORTRAIT): 
02-23 11:45:58.015: I/TestFragment(22629): onCreate(): NULL 
02-23 11:45:58.015: I/TestFragment(22629): onCreateView() 
02-23 11:45:58.035: I/TestFragment(22629): onActivityCreated(): NULL 
AFTER SCREEN ROTATION (LANDSCAPE): 
02-23 11:46:00.615: I/TestFragment(22629): onCreate(): NULL 
02-23 11:46:00.615: I/TestFragment(22629): onCreateView() 
02-23 11:46:00.635: I/TestFragment(22629): onActivityCreated(): NULL 

、およびフラグメントは常にonCreate()onActivityCreated()の両方で、ヌルsavedInstanceStateを取得します。

LogCatは私を与えます。

私のアクティビティonCreate()myFragment.setRetainInstance(true)を試しましたが、それは何も変更されていません。

私のonSaveInstanceState()は@Overrideを持っていますので、誤植のようなものではありません。

私はActionBarSherlockの例(com.actionbarsherlock.sample.shakespeare)の1つと、適切に呼び出されたonSaveInstanceState()のメソッドを持つフラグメントを見てきました。私の知る限りでは、この例は、レイアウトとレイアウトランドXMLの両方に含まれる—フラグメントの正確なコードです。私はメインプロジェクトと同じバージョンのActionBarSherlockを使用してサンプルを構築しています。インスタンスの状態を保存するとその例でうまく動作します。

画面の回転を超えてフラグメント状態を保持するにはどうすればよいですか? onSaveInstanceState()が呼ばれていないのはなぜですか?

+0

tryと@override 'onPause()'/'onResume()'です。 –

+1

回転で呼び出される順序は、onPause()、onDestroy()、onCreate()、onCreateView()、onActivityCreated()、onResume()です。 savedInstanceStateは引き続き常にnullであり、onSaveInstanceState()は呼び出されません。私は明示的にどこでもonSaveInstanceState()を呼び出す必要はないはずですか? – George

+0

2つの異なる場所(ポートレートレイアウトとランドスケープレイアウト)で参照されるフラグメントに問題がありますか?おそらく、Androidには、これが状態を共有してはならない2つの異なる断片であるとのシグナル伝達がありますか? – George

答えて

23

状態を保持するにはmyFragment.setRetainInstance(true)を有効にできますが、これはクラスメンバーに割り当てられた値を保持し、onSaveInstanceStateを使用しないため、常にsavedInstanceStateはnullです。

このフラグメントをホストするFragmentActivityonSaveInstanceStateをオーバーライドしていないことを確認するか、super.onSaveInstanceState(Bundle)を呼び出す必要があります。

+4

Arg!私は自分のアクティビティで 'super.onSaveInstanceState()'を呼んでいませんでした。エリックの答えを聞いてくれてありがとう、私は私の髪を引き裂いていた... – George

0

ローテーション時にフラグメントに異なるレイアウトリソースが必要な場合は、setRetainInstance(true)を使用できません。このpageは、フラグメントのライフサイクルをsetRetainInstance(true)で示しています。

通常のアクティビティのように、すべてのメンバーデータを保持するには、オリジナルの考えはです。ただし、何らかの理由でが呼び出されることはありません。しかし、@ Eric Kokが提案したように、FragmentActivityは正しいです。私が見いだした最良の解決策は、 Fragmentの引数を使用することです。

solutionFyodor Volchyokで表示すると、簡単です。 onSaveInstanceState()でoutState、onViewCreated()でsavedInstanceStateのように動作します。

関連する問題