web-dev-qa-db-ja.com

Fragmentsの `onViewStateRestored`はどのように機能しますか?

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

Fragmentを停止すると、その状態をシングルトン内に自分で保存します(そうです、私もシングルトンが嫌いだと知っていますが、そうするつもりはありませんでした)。したがって、ViewHirarchy全体を再作成し、(キーワードnewを使用して)新しいビューを作成し、その状態を復元してonCreateViewに返す必要があります。このビュー内にチェックボックスもあり、そこから明示的に[〜#〜] not [〜#〜]状態を保存したい。

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

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

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

(TextViewsではなく)Checkboxの状態のみを保存するのはなぜですか?

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

Note私はFragmentv4を使用しているため、onViewStateRestoredに必要なAPI> 17はありません。

25
Rafael T

まあ、断片は少し混乱することがありますが、しばらくすると慣れてきて、結局のところ、それらが友達であることを知るようになります。

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

クラスFの「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");
        }
    }

}