Użycie pakietu zgodności do celu 2.2 przy użyciu fragmentów.
Po przekodowaniu działania w celu użycia fragmentów w aplikacji nie mogłem uzyskać działania zmiany orientacji / zarządzania stanem, więc utworzyłem małą aplikację testową z pojedynczym FragmentActivity i jednym fragmentem.
Dzienniki ze zmian orientacji są dziwne, z wieloma wywołaniami do fragmentów OnCreateView.
Oczywiście czegoś mi brakuje - na przykład odłączam fragment i podłączam go ponownie zamiast tworzyć nową instancję, ale nie widzę żadnej dokumentacji, która wskazywałaby, gdzie idę źle.
Czy ktoś może rzucić trochę światła na to, co tutaj robię źle. Dzięki
Dziennik wygląda następująco po zmianie orientacji.
Initial creation
12-04 11:57:15.808: D/FragmentTest.FragmentTestActivity(3143): onCreate
12-04 11:57:15.945: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:57:16.081: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState null
Orientation Change 1
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): onSaveInstanceState
12-04 11:57:39.031: D/FragmentTest.FragmentTestActivity(3143): onCreate
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState not null
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:57:39.167: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState null
Orientation Change 2
12-04 11:58:32.162: D/FragmentTest.FragmentOne(3143): onSaveInstanceState
12-04 11:58:32.162: D/FragmentTest.FragmentOne(3143): onSaveInstanceState
12-04 11:58:32.361: D/FragmentTest.FragmentTestActivity(3143): onCreate
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState not null
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState not null
12-04 11:58:32.498: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:58:32.498: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState null
Główna aktywność (FragmentActivity)
public class FragmentTestActivity extends FragmentActivity {
/** Called when the activity is first created. */
private static final String TAG = "FragmentTest.FragmentTestActivity";
FragmentManager mFragmentManager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d(TAG, "onCreate");
mFragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
FragmentOne fragment = new FragmentOne();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}
I fragment
public class FragmentOne extends Fragment {
private static final String TAG = "FragmentTest.FragmentOne";
EditText mEditText;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(TAG, "OnCreateView");
View v = inflater.inflate(R.layout.fragmentonelayout, container, false);
// Retrieve the text editor, and restore the last saved state if needed.
mEditText = (EditText)v.findViewById(R.id.editText1);
if (savedInstanceState != null) {
Log.d(TAG, "OnCreateView->SavedInstanceState not null");
mEditText.setText(savedInstanceState.getCharSequence("text"));
}
else {
Log.d(TAG,"OnCreateView->SavedInstanceState null");
}
return v;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.d(TAG, "FragmentOne.onSaveInstanceState");
// Remember the current text, to restore if we later restart.
outState.putCharSequence("text", mEditText.getText());
}
Oczywisty
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:label="@string/app_name"
android:name=".activities.FragmentTestActivity"
android:configChanges="orientation">
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Odpowiedzi:
Nakładasz swoje Fragmenty jeden na drugi.
W przypadku zmiany konfiguracji stary fragment dodaje się do nowego działania po jego odtworzeniu. Przez większość czasu jest to ogromny ból z tyłu.
Możesz zatrzymać występujące błędy, używając tego samego fragmentu, zamiast tworzyć nowy. Po prostu dodaj ten kod:
Ostrzegamy jednak: jeśli spróbujesz uzyskać dostęp do widoków aktywności z wnętrza fragmentu, wystąpią problemy, ponieważ cykle życia ulegną subtelnej zmianie. (Pobieranie widoków z działania nadrzędnego z fragmentu nie jest łatwe).
źródło
"when the activity is destroyed, so are all fragments"
:? Od"When the screen orientation changes, the system destroys and recreates the activity [...]"
.Cytując tę książkę , „aby zapewnić spójne wrażenia użytkownika, system Android zachowuje układ fragmentów i powiązany stos tylny po ponownym uruchomieniu działania z powodu zmiany konfiguracji”. (s. 124)
Sposobem na podejście jest najpierw sprawdzenie, czy tylny stos fragmentów został już zapełniony i utworzenie nowej instancji fragmentu tylko wtedy, gdy nie:
źródło
Metoda onCreate () twojego działania jest wywoływana po zmianie orientacji, jak widzieliśmy. Dlatego nie wykonuj FragmentTransaction, który dodaje Fragment po zmianie orientacji w Twojej aktywności.
Fragmenty powinny i muszą pozostać niezmienione.
źródło
Możesz użyć
@Override
FragmentActivity za pomocąonSaveInstanceState()
. Pamiętaj, aby nie wywoływaćsuper.onSaveInstanceState()
metody w metodzie.źródło
Powinniśmy zawsze unikać wyjątku nullpointer, więc najpierw musimy sprawdzić w metodzie saveinstance informacje o pakunku. aby uzyskać krótkie wyjaśnienie, sprawdź ten link do bloga
źródło
Jeśli robisz tylko projekt, kierownik projektu mówi, że musisz uzyskać ekran funkcji przełączania, ale nie chcesz, aby przełączanie ekranu ładowało inny układ (można utworzyć układ i układ układu-portu.
Automatycznie określisz stan ekranu, załadujesz odpowiedni układ), ze względu na konieczność ponownej inicjalizacji działania lub fragmentu wrażenia użytkownika nie są dobre, a nie bezpośrednio na przełączniku ekranu, do którego odsyłam? Url = YgNfP-vHy-Nuldi7YHTfNet3AtLdN-w__O3z1wLOnzr3wDjYo7X7PYdNyhw8R24ZE22xiKnydni7R0r35s2fOLcHOiLGYT9Qh_fjqtytJki7X7PYdNyhw8R24ZE22xiKnydni7R0r35s2fOLcHOiLGYT9Qh_fjqtytJki7X7PYdNyhw8R24ZE22xiKnydni7R0r35s2fOLcHOiLGYT9Qh_fjqtytJki000082
Założeniem jest, że twój układ używa wagi sposobu układu z layout_weight, w następujący sposób:
Więc moje podejście jest takie, że podczas przełączania ekranu nie trzeba ładować nowego układu pliku widoku, modyfikować układu w onConfigurationChanged dynamicznych wagach, następujące kroki: 1 pierwszy zestaw: AndroidManifest.xml w atrybucie aktywności: android: configChanges = "keyboardHidden | Orientacja | screenSize" Aby zapobiec przełączaniu ekranu, unikaj ponownego ładowania, aby móc monitorować czynność przepisywania onConfigurationChanged 2 lub fragment w metodzie onConfigurationChanged.
źródło
Po zmianie konfiguracji framework utworzy dla ciebie nową instancję fragmentu i doda ją do działania. Więc zamiast tego:
Zrób to:
Zwróć uwagę, że framework dodaje nowe wystąpienie FragmentOne przy zmianie orientacji, chyba że wywołasz setRetainInstance (true), w którym to przypadku doda stare wystąpienie FragmentOne.
źródło