方向の変更が発生したときに、特定のデバイス サイズでアクティビティとフラグメントを切り替えると問題が発生します。私の場合はlarge
画面ですが、アプリによっては他の画面サイズでも発生する可能性があります。私は答えを探しましたが、これに適切に対処するものは何もないようです。
MainActivity と SubordinateActivity という 2 つのアクティビティがあります。MainActivity はアプリへの唯一のエントリ ポイントです。MainActivity は SubordinateActivity を起動します。各アクティビティには、MainFragment と SubordinateFragment という独自のフラグメントがあります。デバイスで実行する場合normal
、画面の向きに関係なく、一度に 1 つのフラグメントに対して十分なスペースしかありません。その場合、各アクティビティは独自のフラグメントを管理します。xlarge
デバイスでは、向きに関係なく、2 つのフラグメントを格納できる十分なスペースがあります。この場合、画面上に 2 つのフラグメントを許可するさまざまなレイアウト ファイルがあります。MainFragment と SubordinateFragment の両方が MainActivity によって管理されます (SubordinateActivity は使用されません)。
問題はlarge
画面で発生します。横向きを使用すると、2 つのフラグメントに十分なスペースがありますが、縦向きでは十分ではありません。それぞれに適切なレイアウト ファイルがあります。横向きモードでは MainActivity が両方のフラグメントを管理し (xlarge
デバイスと同様)、縦向きモードでは各アクティビティが独自のフラグメントを管理します (normal
デバイスと同様)。これにより、次の 2 つのシナリオで問題が発生します。
- SubordinateActivity は縦モードで読み込まれ、向きが横モードに変わります。私が欲しいもの: SubordinateActivity を破棄し、MainActivity をロードする必要があります。SubordinateActivity によって以前に表示されたコンテンツは、独自の SubordinateFragment に表示されます。問題: SubordinateActivity は、ランドスケープ モードで単独でロードされたままになります。
- MainActivity は MainFragment と SubordinateFragment をランドスケープ モードで読み込み、向きはポートレートに切り替わります。私が欲しいもの: 以前に SubordinateFragment に表示されていたコンテンツは、SubordinateActivity によって単独で表示されるようになりました。問題: MainActivity が MainFragment のコンテンツのみで表示されます。
この問題の良い例は、GMail アプリです。私が話していることが明確でない場合に備えて、そのアプリのスクリーンショットをいくつか示します。GMail アプリの UI は実際には私のものよりも複雑ですが、問題は同じです。
これは、GMail 開発者も遭遇したため、他の人が遭遇した問題であると確信しています。すべての可能性には、Android UI のベスト プラクティスに違反するか、アクティビティ コードと XML レイアウトの間に不敬虔なもつれを作成することが含まれているように思われるため、どのような解決策が良いのかわかりません。
ここに私が持っているいくつかのアイデアがありますが、どれも本当に正しいとは思えません:
- 両方のアクティビティで向きの変化を検出し、他のアクティビティを起動して (たとえば、FLAG_ACTIVITY_CLEAR_TOP を使用して)、スタックを下に戻り、以前に読み込まれたアクティビティを新しい意図で読み込みます。方向変更コードはデバイス上でのみ実行する必要があるため、これは問題です
large
。つまり、どのレイアウトが利用可能かをチェックするコードがアクティビティ コードに混在することになります。 - SubordinateActivity を完全に削除します。それは少し余分なようで、
normal
必要に応じて MainFragment と SubordinateFragment を交換できるサイズのデバイスでも、MainActivity はフラグメント自体を管理できます。結局、これで問題が解決するとは思いません。なぜなら、MainActivity は依然としてレイアウト ファイルに依存して、どのフラグメントをいくつ表示するかを指示しているからです。これは、アクティビティがユーザーが行う個別のことを表すという原則にも違反します。
この問題を解決するために私が調べたいくつかのリソースを次に示します。私が言ったように、これは一般的な問題のようですが、標準的な Android ソリューションはないようです。ドキュメントではフラグメントの使用が推奨されており、使用するすべての開発者がこの問題に遭遇するため、これは少し欠点です。
- タスクとバックスタック
- Android バックスタックを制御する方法
- 画面の向きが変わったときに新しいアクティビティを開始する方法は? アンドロイド
- onNewIntent() ライフサイクルと登録済みリスナー
- マルチペイン レイアウト
- フラグメント スタックを維持しながら向きを変更すると、デュアル ペインからシングル ペインに切り替わります
- 向きの変更に伴うアンドロイドフラグメントの問題
- フラグメントは、向きが変更されたときに状態を復元します
概要: デバイスでマルチペイン モードが機能していxlarge
ます。large
私が解決しようとしている問題は、横向きの複数のペインしか処理できないデバイスで、単一ペイン (縦) モードと複数ペイン (横) モードを切り替えることです。