13

Fragmentを典型的なリスト/詳細設計パターンで適切に管理する方法について、私は頭を悩ましています。単一/二重ウィンドウレイアウトでUIの状態とバックスタックを管理する方法

私のレイアウトが正常に動作しているとランドスケープビュー(デュアルペイン)のために、このように構成されている

:私は

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout android:id="@+id/container" ... /> 

:ポートレートビュー(シングルペイン)のための

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout ... > 
    <FrameLayout android:id="@+id/list" ... /> 
    <FrameLayout android:id="@+id/container" ... /> 
</LinearLayout> 

そして、このような適切なレイアウトがデバイスの画面幅に基づいてロードされていることを確認するためにrefs.xmlres/values-w600dp/にも設定してください。

リストアイテムを選択すると、横長ビューにはリストと詳細が並べて表示され、縦長ビューには詳細の全画面のみが表示されます。何も選択されていない場合、横長ビューは左に、空白は右に表示する必要があります。縦長ビューにはリスト全体が表示されます。

example

私は悩みを抱えているところが、ここにあります:

  • は私がリスト+オプションの詳細なレイアウトのための「メイン」Activityを使用し、ために別の「詳細」Activityくださいポートレート、詳細のみのレイアウト?これは、Fragments guideの例のようです。私は一般的にこのように働くことを約束しましたが、オリエンテーションが変わったときに私の細部の断片の状態をどうやって維持していますか?

    は、反対の場合は、上に示した検討 - 詳細が表示されながら、肖像画から風景に回転するメインActivityは、2つのペインのレイアウトを表示することができるように詳細Activityfinish() EDであることが必要であろう意味し、これはまた、詳細を破壊しますフラグメントおよびそのsavedInstanceState。ユーザーが詳細フラグメント内のEditTextフィールドに情報を入力した後、デバイスをローテーションすると、メインセクション(2ペイン)Activityに追加すると、詳細フラグメントのUI状態全体をどのように保持できますか?

  • Activityを1つだけ使用して、自分でFragmentを管理しますか?これにより、オリエンテーションが変更されたときに詳細UIの状態を保持することができます(Androidはこれを自動的に処理するため)、バックスタックになると乱雑になります。

    詳細が表示されているときに風景から肖像画に回転している場合を考えてみましょう。詳細を表示するにはどうすればよいですか?バックスタックを適切に管理するにはどうすればいいですか?ActionBarホームアイコンは、窓?ランドスケープに戻すと、両方のフラグメントが同時に表示されるため、以前に行ったバックスタック操作を元に戻す必要があります。いくつかのより多くの検索後

、私は2つの類似の質問(Switch from dual pane to single pane on orientation change maintaining fragment stackRetain Fragment state between Activities)を見つけましたが、私はこの機能が、フロントアップ、それのために最適なプランを改造しようとしていないよので、私の状況は少し異なります。私は何が欠けていますか?確かにアンドロイドは、複数のバックスタック(Activityの複数の場合)の両方を一度にUI状態(単一のActivityの場合のように)で管理できますか?

答えて

6

私はこれを複数のアクティビティルートに渡して解決しました。 See my answer to "Retain Fragment state between Activities"

キーはFragmentManager.saveFragmentInstanceState()を使用してフラグメントのUIの状態を保存し、Fragment.setInitialSavedState()を使用して、同じフラグメントを別のアクティビティでインスタンス化するときに復元しました。

私の目的として、私は2つのケースでUI状態を保存する必要があることを発見しました。私は自分のフラグメント内にヘルパーメソッドpublic void saveState()を作成し、replace()を使用する直前にフラグメントの独自のonPause()メソッドと私の "main"アクティビティからこれを呼び出し、デュアルペインレイアウトにフラグメントの新しいインスタンスをアタッチします。

このタイプのシングル/デュアルペインレイアウトシナリオに必要なバックスタック操作が可能か、または単一アクティビティアプローチでonBackPressedをオーバーライドし、手動でバックスタックをシミュレートする必要があるかどうかはまだ分かります。

4

アクティビティは1つしか使用できませんが、縦向きの場合はバックスタックを管理する必要があります。

アプリの動作を説明すると、4つの状態があるかもしれません:

  • 状態A:肖像画、リストのフラグメントを示します。
  • 状態B:バックグラウンド上のリストフラグメントを含む詳細フラグメントを示すポートレート。
  • 状態C:ランドスケープ、左のリストフラグメントと右の空白スペースを示します。
  • 状態D:ランドスケープ。リストフラグメントと詳細フラグメントの両方を並べて表示します。

あなたは状態Dになっているとします(両方のフラグメントでFAとFBと呼んでください)、電話機の向きを変更したとします。次の状態はB状態にする必要がありますが、ポートレートのレイアウトにはFrameLayoutという1つしかないという問題があります。使用して1つのペインのレイアウトとして、以下:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout android:id="@+id/list" ... /> 

AndroidはFAを再作成し、それがそのFrameLayoutに添付しています。一方、FBは再作成されますが、コンテナは関連付けられていないので、表示されません。この時点で、FBと同じ内容の別のフラグメントFB2を作成し、それをFAに置き換えることができます。あなたはあなたのバックスタックにFB-FB2を持ち、FBは隠しています。

方向をもう一度変更すると(状態Dが予想される)、onSaveInstanceState()を使用して、バックスタックスからFB2をpopBackStack()でポップすることができます。つまり、再びFAとFBがあります。 FB2を削除する前に、そのコンテンツをFBにコピーすることもできます。アプリケーションが再び状態Dになると、FBはそのFrameLayoutを持ちます。

あなたが気をつけなければならないいくつかの他のトランジションや状況がありますが、主な考え方はそうです。

これは非常に洗練された解決策ではないので、この問題を解決するには、より良い、多分効率的な(断片化を複製することなく)方法が必要であると確信しています。

関連する問題