32

Fragment の内部状態について本当に混乱しています。別のフラグメントが表示される必要がある場合、一度に 1 つのフラグメントのみを保持するアクティビティがあり、それを置き換えます。アクティビティが呼び出されている場合にのみ、ドキュメントからonSaveInstanceState呼び出されます(私の場合は呼び出されません)。onSaveInstanceState

Fragment を停止すると、その状態を自分で Singleton 内に格納します (そうです、Singleton も嫌いなのはわかっていますが、そうすることは私の考えではありませんでした)。したがって、全体を再作成し、ViewHirarchy(キーワードを使用してnew) 新しいビューを作成し、その状態を復元して に戻す必要がありonCreateViewます。また、このビュー内にチェックボックスがあり、その状態を明示的に保存したくありません。

ただし、FragmentManager「インテリジェント」になりたいと思っておりonViewStateRestored、自分で作成したことのないバンドルを呼び出し、古い状態を「復元」CheckBoxして新しいチェックボックスに適用します。これは非常に多くの質問を投げかけます:

からバンドルを制御できますonViewStateRestoredか?

FragmentManager は (おそらくガベージ コレクションされた) CheckBox の状態をどのように取得し、それを新しいものに適用しますか?

チェックボックスの状態のみを保存するのはなぜですか (TextView の状態ではありませんか??)

要約すると、どのように機能しonViewStateRestoredますか?

注 Fragmentv4 を使用しているため、17 を超える API は必要ありません。onViewStateRestored

4

1 に答える 1

36

フラグメントは少し混乱することがありますが、しばらくするとフラグメントに慣れ、最終的にフラグメントがあなたの友達であることを学びます。

フラグメントの onCreate() メソッドの場合は、次のようにします。 setRetainInstance(true); ビューの表示状態は保持されますが、それ以外の場合は保持されません。

クラス F の "f" というフラグメントがあるとします。そのライフサイクルは次のようになります。

F.newInstance();
F();
F.onCreate();
F.onCreateView();
F.onViewStateRestored;
F.onResume();

この時点で、フラグメントが画面に表示されます。デバイスがローテーションされると仮定すると、フラグメント情報を保持する必要があります。ローテーションによってトリガーされるイベントの流れは次のとおりです。

F.onSaveInstanceState(); //save your info, before the fragment is destroyed, HERE YOU CAN CONTROL THE SAVED BUNDLE, CHECK EXAMPLE BELLOW.
F.onDestroyView(); //destroy any extra allocations your have made
//here starts f's restore process
F.onCreateView(); //f's view will be recreated
F.onViewStateRestored(); //load your info and restore the state of f's view
F.onResume(); //this method is called when your fragment is restoring its focus, sometimes you will need to insert some code here.


//store the information using the correct types, according to your variables.
@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putSerializable("foo", this.foo);
    outState.putBoolean("bar", true);
}

@Override
public void onViewStateRestored(Bundle inState) {
    super.onViewStateRestored(inState);
    if(inState!=null) {
        if (inState.getBoolean("bar", false)) {
            this.foo = (ArrayList<HashMap<String, Double>>) inState.getSerializable("foo");
        }
    }

}
于 2015-08-28T13:26:08.153 に答える