アプリに「標準」フラグメント ナビゲーションを実装する必要があります (リンクを参照してください)。
問題は、デバイスが縦向きモードの場合は 1 つのフラグメントのみが表示され、横向きモードに回転すると 2 つのフラグメントが表示されるはずです。
私はこれを2つの異なる方法でやろうとしました:
1) 縦向きと横向きのレイアウトが異なるアクティビティを 1 つだけ使用します。
縦向きレイアウト xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="@+id/main_frame_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
そして、ここに横向きのレイアウトがあります:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="horizontal" >
<FrameLayout
android:id="@+id/main_frame_fragment_container_left"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
<FrameLayout
android:id="@+id/main_frame_fragment_container_right"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
アクティビティの onCreateメソッド:
private static ItemsFragment mItemsFragment;
private static ItemDetailsFragment mItemDetailsFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (mItemsFragment == null) {
mItemsFragment = ItemsFragment.newInstance();
}
if (mItemDetailsFragment == null) {
mItemDetailsFragment = ItemDetailsFragment.newInstance();
}
if (isLandscape()) {
getSupportFragmentManager().beginTransaction().replace(R.id.main_frame_fragment_container_left, mItemsFragment)
.commit();
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_frame_fragment_container_right, mItemDetailsFragment).commit();
} else {
getSupportFragmentManager().beginTransaction().replace(R.id.main_frame_fragment_container, mItemsFragment)
.commit();
}
}
そして、それが2番目のフラグメントをリフレッシュする方法です:
Bundle bundle = new Bundle();
bundle.putSerializable(BaseFragment.KEY_BUNDLE_ITEM, response.getItem());
mItemDetailsFragment = ItemDetailsFragment.newInstance(bundle);
if (isLandscape()) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_frame_fragment_container_right, mItemDetailsFragment).commit();
} else {
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_frame_fragment_container, mItemDetailsFragment).addToBackStack(null).commit();
}
また、フラグメントの状態を保存して復元するので、ローテーション後にデータが消えることはありません。通常、このコードは私の場合は正しく機能します。
2) 2 つのアクティビティを使用し、最初のアクティビティの縦向きモードと横向きモードに同じレイアウトを使用します。
xml レイアウトは、ランドスケープの前のものと同じです。
<FrameLayout
android:id="@+id/main_frame_fragment_container_left"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
<FrameLayout
android:id="@+id/main_frame_fragment_container_right"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
onCreateメソッド (最初のケースのように、フラグメント エンティティは静的ではないことに注意してください): private ItemsFragment mItemsFragment; プライベート ItemDetailsFragment mItemDetailsFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
mItemsFragment = ItemsFragment.newInstance();
mItemDetailsFragment = ItemDetailsFragment.newInstance();
getSupportFragmentManager().beginTransaction().replace(R.id.main_frame_fragment_container_left, mItemsFragment)
.commit();
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_frame_fragment_container_right, mItemDetailsFragment).commit();
}
}
デバイスが縦向きモードの場合は、新しいアクティビティを開始します。
if (isLandscape()) {
Bundle bundle = new Bundle();
bundle.putSerializable(BaseFragment.KEY_BUNDLE_ITEM, response.getItem());
mItemDetailsFragment = ItemDetailsFragment.newInstance(bundle);
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_frame_fragment_container_right, mItemDetailsFragment).commit();
} else {
Intent intent = new Intent(getApplicationContext(), DetailsActivity.class);
intent.putExtra(KEY_ITEM, response.getItem());
startActivity(intent);
}
そして最後に、2 番目のアクティビティのonCreateメソッド:
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.activity_details);
if (isLandscape()) {
finish();
}
Item item = (Item) getIntent().getExtras().getSerializable(KEY_ITEM);
Bundle bundle = new Bundle();
bundle.putSerializable(BaseFragment.KEY_BUNDLE_ITEM, item);
ItemDetailsFragment mItemDetailsFragment = ItemDetailsFragment.newInstance(bundle);
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_frame_fragment_container, mItemDetailsFragment).commit();
}
デバイスが横向きモードに回転すると、2 番目のアクティビティが終了し、1 番目のアクティビティに 2 つのフラグメントが表示されます (予想どおり)。
質問:
最初のケースでは、フラグメントを静的変数として保存します。このため、ポートレート モードまたはランドスケープ モードで 2 番目のフラグメントの状態を変更してもかまいません (同じフラグメントが使用されます)。しかし、静的フィールドとして保存するのは良い考えではないと思います。
2 番目のケースでは、Activity A Fragment B (横向き) と Activity B Fragment B (縦向き) を同期する方法がわかりません。フラグメントで何かを変更して (つまり、トグル ボタンなど)、デバイスを回転させると、別のフラグメントに変更を適用する必要があります。
一般的に、どのケースが良いですか? また、2 番目の場合、どうすれば同期の問題を解決できますか? または、別の簡単な方法があるかもしれません。読んでくれてありがとう、あなたが私を助けてくれることを願っています:)