Verarbeiten der Fragmentduplizierung auf dem Bildschirm Drehen (mit Beispielcode)

Es gibt einige ähnliche Antworten, aber nicht auf diese Situation.

Meine Situation ist einfach.

Ich habe eine Aktivität mit zwei verschiedenen Layouts, eines im Hochformat und eines im Querformat.

ImPorträt, ich benutze<FrameLayout> und hinzufügenFragment hineindynamisch.

ImLandschaft, ich benutze<fragment> so dasFragment iststatisch. (in der Tat ist das egal)

Es beginnt zuerst inPorträt, dann habe ich dieFragment einfach nur:

ListFrag listFrag = new ListFrag();
getSupportFragmentManager().beginTransaction()
        .replace(R.id.FragmentContainer, listFrag).commit();

woherListFrag extends ListFragment.

Dann drehe ich einen Bildschirm.Ich habe festgestellt, dass listFrag im Querformat neu erstellt wird. (In dem mir der aufgefallen istonCreate() Methode wird erneut mit einem Nicht-Null-Bundle aufgerufen)

Ich habe versucht zu verwendensetRetainInstance(false) wie @NPike sagte indieser Beitrag. Aber diegetRetainInstance() ist schonfalse standardmäßig. Es tut nicht das, was ich erwartet hattedie docs sagte. Könnte jemand bitte erklären?

Das Fragment, mit dem ich es zu tun habe, ist aListFragment, was tutsetListAdapter() imonCreate(). Also dieif (container == null) return null; Methode kann hier nicht verwendet werden. (oder ich weiß nicht, wie man sich bewirbt).

Ich habe einige Hinweise vondieser Beitrag. Sollte ich es benutzenif (bundle != null) setListAdapter(null); else setListAdapter(new ...); in meinemListFragment? Aber gibt es eine schönere Möglichkeit, das Fragment tatsächlich zu entfernen / löschen, wenn es zerstört / abgetrennt wird, als es in seiner Erstellungszeit zu tun? (so wie dieif (container == null) return null; Methode)

Bearbeiten:

Der einzige gute Weg, den ich gefunden habe, ist zu tungetSupportFragmentManager().beginTransaction().remove(getSupportFragmentManager().findFragmentById(R.id.FragmentContainer)).commit(); imonSaveInstanceState(). Aber es wird andere Probleme aufwerfen.

Wenn der Bildschirm teilweise verdeckt ist, z. B. wenn WhatsApp- oder TXT-Dialogfelder angezeigt werden, wird das Fragment ebenfalls ausgeblendet.(Dies ist ein relativ kleines, nur visuelles Problem.)

Beim Drehen des Bildschirms wird die Aktivität vollständig zerstört und neu erstellt. Also kann ich das Fragment wieder hinzufügenonCreate(Bundle) oderonRestoreInstanceState(Bundle). Aber im Fall von (1) sowie beim Wechseln von Aktivitäten auch nichtonCreate(Bundle) NochonRestoreInstanceState(Bundle) wird aufgerufen, wenn der Benutzer zu meiner Aktivität zurückkehrt. Ich kann die Aktivität nirgendwo neu erstellen (und Daten aus dem Bundle abrufen).

Es tut mir leid, dass ich nicht klar gesagt habe, dass ich bereits eine Entscheidung getroffen habe, die diegetSupportFragmentManager()...replace(...).commit(); Linie läuft nur im Hochformat.

Beispielcode

Ich habe den einfachen Code extrahiert, um die Situation besser zu veranschaulichen :)

MainActivity.java

package com.example.fragremovetrial;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;

public class MainActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (findViewById(R.id.FragmentContainer) != null) {
            System.out.println("-- Portrait --");       // Portrait
            ListFrag listFrag = new ListFrag();
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.FragmentContainer, listFrag).commit();
        } else {
            System.out.println("-- Landscape --");      // Landscape
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (findViewById(R.id.FragmentContainer) != null) {
            System.out.println("getRetainInstance = " +
                    getSupportFragmentManager().findFragmentById(R.id.FragmentContainer).getRetainInstance());
        }
    }
}

layout / activity_main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/FragmentContainer"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />

layout-land / activity_main.xml (egal)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
</LinearLayout>

ListFrag.java

package com.example.fragremovetrial;

import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.widget.ArrayAdapter;

public class ListFrag extends ListFragment {
    private String[] MenuItems = { "Content A", "Contnet B" };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        System.out.println("ListFrag.onCreate(): " + (savedInstanceState == null ? null : savedInstanceState));

        setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, MenuItems));
    }
}

Beachten Sie, dass ich Folgendes habe

Debuggen von Nachrichten

- Porträt -
ListFrag.onCreate (): null
getRetainInstance = false

(Port drehen -> Land)

ListFrag.onCreate (): Bundle [{android: view_state=android.util.SparseArray@4052dd28}]
- Landschaft -
Die zuvor fokussierte Ansicht hat beim Speichern die ID 16908298 gemeldet, wurde jedoch beim Wiederherstellen nicht gefunden.

(Land drehen -> Hafen)

ListFrag.onCreate (): Bundle [{android: view_state=android.util.SparseArray@405166c8}]
- Porträt -
ListFrag.onCreate (): null
getRetainInstance = false

(Port drehen -> Land)

ListFrag.onCreate (): Bundle [{android: view_state=android.util.SparseArray@4050fb40}]
- Landschaft -
Die zuvor fokussierte Ansicht hat beim Speichern die ID 16908298 gemeldet, wurde jedoch beim Wiederherstellen nicht gefunden.

(Land drehen -> Hafen)

ListFrag.onCreate (): Bundle [{android: view_state=android.util.SparseArray@40528c60}]
- Porträt -
ListFrag.onCreate (): null
getRetainInstance = false

wo die Anzahl der Fragmente erstellt wirdnicht Erhöhen Sie sich unendlich, während sich der Bildschirm weiter dreht, was ich nicht erklären kann. (bitte helfen)

Antworten auf die Frage(4)

Ihre Antwort auf die Frage