Zmieniono stan przywracania fragmentów w orientacji
Muszę zaimplementować nawigację „standart” w mojej aplikacji (zobaczpołączyć).
Problem polega na tym, że urządzenie jest w trybie portretowym, powinien być pokazany tylko 1 fragment, a gdy zostanie obrócony do trybu poziomego, należy pokazać 2 fragmenty.
Próbowałem to zrobić na dwa różne sposoby:
1) Używam tylko 1 aktywności z różnymi układami portretów i krajobrazu.
Układ pionowy 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>
A oto układ krajobrazu:
<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>
AktywnośćonCreate metoda:
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();
}
}
I tak odświeżyłem drugi fragment:
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();
}
Również zapisuję i przywracam stany fragmentów, więc moje dane nie znikają po rotacjach. Ogólnie rzecz biorąc, ten kod działa poprawnie w moim przypadku.
2) Używam 2 zajęć i tego samego układu dla trybów portretowych i krajobrazowych 1. aktywności.
Układ xml jest taki sam jak w poprzednim dla krajobrazu:
<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 metoda (uwaga, że fragmenty nie są statyczne, tak jak w pierwszym przypadku): private ItemsFragment mItemsFragment; private 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();
}
}
A teraz, jeśli urządzenie jest w trybie pionowym, rozpoczynam nową aktywność:
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);
}
I wreszcie, druga aktywnośćonCreate metoda:
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();
}
Po obróceniu urządzenia do trybu poziomego kończy się druga aktywność i widzę moją pierwszą aktywność z 2 fragmentami (zgodnie z oczekiwaniami).
Pytanie:
W pierwszym przypadku zapisuję fragmenty jako zmienne statyczne iz tego powodu nie obchodzi mnie, czy zmienię stan drugiego fragmentu w trybach pionowym czy poziomym (ten sam fragment jest używany). Ale nie sądzę, żeby to dobry pomysł zapisać jako statyczne pola.
W drugim przypadku nie wiem, jak zsynchronizować aktywność A Fragment B (krajobraz) i Aktywność B Fragment B (portret). Jeśli zmienię coś we fragmencie (mam na myśli przełącznik, itp.) I obrócę urządzenie, zmiany należy zastosować w innym fragmencie.
Zasadniczo, jaki przypadek jest lepszy, a jeśli drugi, jak rozwiązać problem z synchronizacją? A może jest inny, łatwiejszy sposób. Dzięki za przeczytanie, mam nadzieję, że możesz mi pomóc :)