Verwenden des Kompatibilitätspakets für das Ziel 2.2 mithilfe von Fragmenten.
Nach dem Neukodieren einer Aktivität zur Verwendung von Fragmenten in einer App konnte ich die Orientierungsänderungen / Statusverwaltung nicht zum Laufen bringen. Daher habe ich eine kleine Test-App mit einer einzelnen FragmentActivity und einem einzelnen Fragment erstellt.
Die Protokolle der Orientierungsänderungen sind seltsam, mit mehreren Aufrufen der Fragmente OnCreateView.
Mir fehlt offensichtlich etwas - wie das Entfernen des Fragments und das erneute Anhängen, anstatt eine neue Instanz zu erstellen, aber ich kann keine Dokumentation sehen, die darauf hinweist, wo ich falsch liege.
Kann jemand etwas Licht ins Dunkel bringen, was ich hier falsch mache? Vielen Dank
Das Protokoll sieht nach Orientierungsänderungen wie folgt aus.
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
Hauptaktivität (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();
}
Und das 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());
}
Manifest
<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>
Antworten:
Sie legen Ihre Fragmente übereinander.
Wenn eine Konfigurationsänderung auftritt, fügt sich das alte Fragment der neuen Aktivität hinzu, wenn es neu erstellt wird. Dies ist die meiste Zeit ein massiver Schmerz im hinteren Bereich.
Sie können das Auftreten von Fehlern stoppen, indem Sie dasselbe Fragment verwenden, anstatt ein neues neu zu erstellen. Fügen Sie einfach diesen Code hinzu:
Seien Sie jedoch gewarnt: Probleme treten auf, wenn Sie versuchen, aus dem Fragment heraus auf Aktivitätsansichten zuzugreifen, da sich die Lebenszyklen geringfügig ändern. (Abrufen von Ansichten von einer übergeordneten Aktivität aus einem Fragment ist nicht einfach).
quelle
"when the activity is destroyed, so are all fragments"
? Seit"When the screen orientation changes, the system destroys and recreates the activity [...]"
.Um dieses Buch zu zitieren : "Um eine konsistente Benutzererfahrung zu gewährleisten, behält Android das Fragment-Layout und den zugehörigen Backstack bei, wenn eine Aktivität aufgrund einer Konfigurationsänderung neu gestartet wird." (S. 124)
Um dies zu erreichen, müssen Sie zunächst prüfen, ob der Fragment-Backstack bereits gefüllt ist, und die neue Fragmentinstanz nur dann erstellen, wenn dies nicht der Fall ist:
quelle
Die onCreate () -Methode Ihrer Aktivität wird nach der Orientierungsänderung aufgerufen, wie Sie gesehen haben. Führen Sie daher nicht die FragmentTransaction aus, die das Fragment nach der Orientierungsänderung in Ihrer Aktivität hinzufügt.
Die Fragmente sollten und müssen unverändert bleiben.
quelle
Sie können
@Override
die FragmentActivity mitonSaveInstanceState()
. Bitte rufen Sie diesuper.onSaveInstanceState()
in der Methode nicht auf.quelle
Wir sollten immer versuchen, eine Nullzeiger-Ausnahme zu verhindern, daher müssen wir zuerst in der saveinstance-Methode nach Bundle-Informationen suchen. Für eine kurze Erklärung überprüfen Sie diesen Blog- Link
quelle
Bei einer Konfigurationsänderung erstellt das Framework eine neue Instanz des Fragments für Sie und fügt es der Aktivität hinzu. Also stattdessen:
mach das:
Beachten Sie, dass das Framework bei einer Änderung der Ausrichtung eine neue Instanz von FragmentOne hinzufügt, es sei denn, Sie rufen setRetainInstance (true) auf. In diesem Fall wird die alte Instanz von FragmentOne hinzugefügt.
quelle
Wenn Sie nur ein Projekt ausführen, sagt der Projektmanager, dass Sie einen Schaltfunktionsbildschirm erreichen müssen, aber nicht möchten, dass das Umschalten unterschiedliche Layouts lädt (kann Layout und Layout-Port-System erstellen.
Sie bestimmen automatisch den Bildschirmstatus, laden das entsprechende Layout), da die Aktivität oder das Fragment neu initialisiert werden muss, ist die Benutzererfahrung nicht gut, nicht direkt auf dem Bildschirmschalter, auf den ich mich beziehe? URL = YgNfP-vHy-Nuldi7YHTfNet3AtLdN-w__O3z1wLOnzr3wDjYo7X7PYdNyhw8R24ZE22xiKnydni7R0r35s2fOLcHOiLGYT9Qh_fjqtyt110 =
Die Voraussetzung ist, dass Ihr Layout das Gewicht des Layouts des layout_weight wie folgt verwendet:
Mein Ansatz ist es also, beim Umschalten des Bildschirms kein neues Layout der Ansichtsdatei zu laden und das Layout in den dynamischen Gewichten von onConfigurationChanged zu ändern. Führen Sie dazu die folgenden Schritte aus: 1 Erster Satz: AndroidManifest.xml im Aktivitätsattribut: android: configChanges = "keyboardHidden | orientierung | screenSize" Um ein Umschalten des Bildschirms zu verhindern, vermeiden Sie ein erneutes Laden, um in onConfigurationChanged 2 die Aktivität oder das Fragment in der onConfigurationChanged-Methode neu zu schreiben.
quelle