Best Practice zum Instanziieren eines neuen Android-Fragments

706

Ich habe zwei allgemeine Methoden zum Instanziieren eines neuen Fragments in einer Anwendung gesehen:

Fragment newFragment = new MyFragment();

und

Fragment newFragment = MyFragment.newInstance();

Die zweite Option verwendet eine statische Methode newInstance()und enthält im Allgemeinen die folgende Methode.

public static Fragment newInstance() 
{
    MyFragment myFragment = new MyFragment();
    return myFragment;
}

Zuerst dachte ich, der Hauptvorteil sei die Tatsache, dass ich die newInstance () -Methode überladen könnte, um beim Erstellen neuer Instanzen eines Fragments Flexibilität zu bieten - aber ich könnte dies auch tun, indem ich einen überladenen Konstruktor für das Fragment erstelle.

Habe ich etwas verpasst?

Was sind die Vorteile eines Ansatzes gegenüber dem anderen? Oder ist es nur eine gute Übung?

Graham Smith
quelle
Wenn es Parameter gibt, gibt es keine Wahl, und dies wird hier ausführlich beantwortet. Dennoch bleibt die Frage nach der argumentlosen Konstruktion des Fragments.
rds
1
Nachdem ich etwas über Factory-Muster gelernt hatte und wie eine aufrufende Klasse, die ein Objekt selbst nicht instanziiert, dabei hilft, sie zu entkoppeln, dachte ich, dies wäre eine Stärke für die newInstance () -Methode. Liege ich falsch? Ich habe dieses spezielle Argument nicht als Vorteil gesehen.
Mobile Anwendungen

Antworten:

1136

Wenn Android beschließt, Ihr Fragment später neu zu erstellen, wird der Konstruktor ohne Argumente Ihres Fragments aufgerufen. Das Überladen des Konstruktors ist also keine Lösung.

Wenn dies gesagt ist, besteht die Möglichkeit, Inhalte an Ihr Fragment zu übergeben, damit sie verfügbar sind, nachdem ein Fragment von Android neu erstellt wurde, darin, ein Bundle an die setArgumentsMethode zu übergeben.

Wenn wir beispielsweise eine Ganzzahl an das Fragment übergeben möchten, verwenden wir Folgendes:

public static MyFragment newInstance(int someInt) {
    MyFragment myFragment = new MyFragment();

    Bundle args = new Bundle();
    args.putInt("someInt", someInt);
    myFragment.setArguments(args);

    return myFragment;
}

Und später im Fragment können onCreate()Sie auf diese Ganzzahl zugreifen, indem Sie Folgendes verwenden:

getArguments().getInt("someInt", 0);

Dieses Bundle wird auch dann verfügbar sein, wenn das Fragment irgendwie von Android neu erstellt wurde.

Beachten Sie auch: setArgumentsKann nur aufgerufen werden, bevor das Fragment an die Aktivität angehängt ist.

Dieser Ansatz ist auch in der Android-Entwicklerreferenz dokumentiert: https://developer.android.com/reference/android/app/Fragment.html

yydl
quelle
7
@Vlasto Leider können statische Methoden nicht überschrieben werden.
AJD
8
@yydl Ich glaube, ich vermisse hier etwas. Könnten Sie hier sowieso keinen Konstruktor verwenden, der das Bundle erstellt und setArguments () aufruft, da er nur von Ihrem Code aufgerufen wird (und nicht, wenn Android Ihren neu erstellt?) Fragment)?
Mike Tunnicliffe
9
@mgibson Sie müssen ein Bundle verwenden, wenn die Daten verfügbar sein sollen, wenn das Fragment später neu erstellt wird.
Yydl
114
Die Erzwingung, einen Konstruktor ohne Argumente für Fragmente zu erstellen, ist möglicherweise das größte Problem in der gesamten Programmierung. Es erzwingt einen vollständigen Paradigmenwechsel bei der Objekterstellung und -initialisierung. Wenn Sie neu bei Android sind und auf diesen Thread gestoßen sind, lesen Sie die Antwort oben immer und immer wieder.
Rmirabelle
9
Ich würde mit dieser Behauptung argumentieren. Erstens ist die Typensicherheit ein Sprachproblem, kein Rahmenproblem. Zweitens, IMO, betritt das Framework den Bereich "Dinge, die Ihre API niemals tun darf". Wenn ich die Kongressbibliothek an meinen Fragmentkonstruktor übergeben möchte, sollte ich das dürfen. Der Konstruktorvertrag "no-args" beendet im Grunde die Verwendung der Abhängigkeitsinjektion in Fragmenten - Major Yuck.
Rmirabelle
95

Der einzige Vorteil bei der Verwendung der newInstance(), die ich sehe, sind die folgenden:

  1. Sie haben eine einzige Stelle, an der alle vom Fragment verwendeten Argumente gebündelt werden können, und Sie müssen den folgenden Code nicht jedes Mal schreiben, wenn Sie ein Fragment instanziieren.

    Bundle args = new Bundle();
    args.putInt("someInt", someInt);
    args.putString("someString", someString);
    // Put any other arguments
    myFragment.setArguments(args);
  2. Dies ist eine gute Möglichkeit, anderen Klassen mitzuteilen, welche Argumente voraussichtlich korrekt funktionieren (obwohl Sie in der Lage sein sollten, Fälle zu behandeln, wenn in der Fragmentinstanz keine Argumente gebündelt sind).

Ich gehe davon aus, dass die Verwendung einer Statik newInstance()zum Instanziieren eines Fragments eine gute Vorgehensweise ist.

500865
quelle
4
1) Wie unterscheidet sich das vom Einfügen der Logik in einen Konstruktor? Beides sind einzelne Stellen, an denen Sie diese Logik einfügen. 2) Wie unterscheiden sich Parameter in einer statischen Factory von Parametern in einem Konstruktor? Beide sagen, welche Argumente erwartet werden. Mein Punkt ist, dass es sicher ein anderes Paradigma ist, aber es gibt keinen klaren Vorteil gegenüber der Verwendung von Konstruktoren.
RJ Cuthbertson
2
Sie können keine benutzerdefinierten Konstruktoren für Fragmente verwenden. Framework verwendet den Konstruktor no argument zum Wiederherstellen von Fragmenten.
500865
5
Ja, da stimme ich Ihnen zu. Ich sage konzeptionell, dass es keinen Vorteil hat, das statische Factory-Muster anstelle überladener Konstruktoren zu verwenden und umgekehrt. Ihre beiden Punkte sind in beiden Mustern gültig. Es gibt keinen Vorteil, einen über den anderen zu verwenden. Android zwingt Sie, das statische Factory-Muster zu verwenden - die Verwendung des einen oder anderen hat jedoch keinen Vorteil.
RJ Cuthbertson
pastebin.com/EYJzES0j
RJ Cuthbertson
@RJCuthbertson Ein möglicher Vorteil wäre die Möglichkeit, Unterklassen der Klasse der statischen Factory-Methode zu erstellen und zurückzugeben, dh eine geeignete Unterklasse für die Situation zurückzugeben.
Urgentx
62

Es gibt auch einen anderen Weg:

Fragment.instantiate(context, MyFragment.class.getName(), myBundle)
user1145201
quelle
Wenn ich mich nicht irre, ist dies nur möglich, wenn Sie die Android-Support-Bibliothek verwenden.
Timo
2
Versuchte dies mit der Support-Bibliothek, aber in onCreateView (in meinem Fragment) war das übergebene Bundle null, also habe ich mich für die Option setArguments / getArguments entschieden und es hat funktioniert (für alle, die dies lesen).
Jrop
1
Interessanterweise habe ich diesen Ansatz noch nie gesehen. Hat es irgendwelche Vorteile gegenüber anderen Ansätzen zum Instanziieren eines Fragments?
Igor Ganapolsky
22
Aus den Entwickler docs ,instantiate() Creates a new instance of a Fragment with the given class name. This is the same as calling its empty constructor.
Brian Bowman
2
Obwohl sie dasselbe wie das Aufrufen eines leeren Konstruktors erwähnten. "args.setClassLoader (f.getClass (). getClassLoader ());" wird unten für Bündel Argumente genannt
Gökhan Barış Aker
49

Während @yydl einen überzeugenden Grund dafür angibt, warum die newInstanceMethode besser ist:

Wenn Android beschließt, Ihr Fragment später neu zu erstellen, wird der Konstruktor ohne Argumente Ihres Fragments aufgerufen. Das Überladen des Konstruktors ist also keine Lösung.

Es ist immer noch möglich, einen Konstruktor zu verwenden . Um zu sehen, warum dies so ist, müssen wir zuerst sehen, warum die obige Problemumgehung von Android verwendet wird.

Bevor ein Fragment verwendet werden kann, wird eine Instanz benötigt. Android ruft YourFragment()(der Konstruktor ohne Argumente ) auf, um eine Instanz des Fragments zu erstellen. Hier wird jeder überladene Konstruktor, den Sie schreiben, ignoriert, da Android nicht wissen kann, welchen Sie verwenden sollen.

Während der Lebensdauer einer Aktivität wird das Fragment wie oben erstellt und von Android mehrmals zerstört. Dies bedeutet, dass Daten, die in das Fragmentobjekt selbst eingefügt werden, verloren gehen, sobald das Fragment zerstört wird.

Um dies zu umgehen, fordert Android Sie auf, Daten mit einem Bundle(Aufruf setArguments()) zu speichern , auf den dann zugegriffen werden kann YourFragment. Argumente bundlewerden von Android geschützt und sind daher garantiert dauerhaft .

Eine Möglichkeit, dieses Bundle festzulegen, ist die Verwendung einer statischen newInstanceMethode:

public static YourFragment newInstance (int data) {
    YourFragment yf = new YourFragment()
    /* See this code gets executed immediately on your object construction */
    Bundle args = new Bundle();
    args.putInt("data", data);
    yf.setArguments(args);
    return yf;
}

Ein Konstruktor:

public YourFragment(int data) {
    Bundle args = new Bundle();
    args.putInt("data", data);
    setArguments(args);
}

kann genau das gleiche tun wie die newInstanceMethode.

Dies würde natürlich fehlschlagen und ist einer der Gründe, warum Android möchte, dass Sie die newInstanceMethode verwenden:

public YourFragment(int data) {
    this.data = data; // Don't do this
}

Zur weiteren Erklärung hier die Fragmentklasse von Android:

/**
 * Supply the construction arguments for this fragment.  This can only
 * be called before the fragment has been attached to its activity; that
 * is, you should call it immediately after constructing the fragment.  The
 * arguments supplied here will be retained across fragment destroy and
 * creation.
 */
public void setArguments(Bundle args) {
    if (mIndex >= 0) {
        throw new IllegalStateException("Fragment already active");
    }
    mArguments = args;
}

Beachten Sie, dass Android darum bittet, dass die Argumente nur bei der Erstellung festgelegt werden, und garantiert, dass diese beibehalten werden.

BEARBEITEN : Wie in den Kommentaren von @JHH ausgeführt, stellt Java Ihrem Fragment keinen Standardkonstruktor ohne Argumente zur Verfügung, wenn Sie einen benutzerdefinierten Konstruktor bereitstellen, für den einige Argumente erforderlich sind . Dazu müssten Sie einen Konstruktor ohne Argumente definieren. Dies ist Code, den Sie mit der newInstanceFactory-Methode vermeiden können .

BEARBEITEN : Android erlaubt nicht mehr die Verwendung eines überladenen Konstruktors für Fragmente. Sie müssen die newInstanceMethode verwenden.

ps95
quelle
Wann würde man die Verwendung von Android rechtfertigen: configChanges = "Ausrichtung | TastaturHidden | Bildschirmgröße"?
Luke Allison
1
Android Studio gibt jetzt einen Fehler für alle nicht standardmäßigen Konstruktoren in Fragmenten aus, sodass dies nicht mehr funktioniert.
Sheharyar
6
Heiliger Mann, ich frage mich, wie viele Droidenentwickler jemals Code außerhalb von Droiden geschrieben haben. Dies ist verrückt, dass wir den von Ihnen beschriebenen Ansatz nicht verwenden können. Es gibt KEINE zwingenden Argumente aus einem Kommentar, warum wir die statische Factory-Methode verwenden MÜSSEN. Es ist noch beunruhigender, dass sie beim Kompilieren einen Fehler auslösen würden. Dies ist definitiv die beste Antwort und zeigt, dass sfm keinen Nutzen bringt.
MPavlak
3
Nun, es gibt einen subtilen Grund. Es steht Ihnen frei, Ihren eigenen Konstruktor mit Argumenten zu erstellen, es muss jedoch auch ein Konstruktor ohne Argumente vorhanden sein . Da Klassen haben immer einen impliziten nicht argument Konstruktor , es sei denn ein Konstruktor mit args explizit definiert ist , bedeutet dies , dass würden Sie sowohl Ihren arg-Konstruktor definieren müssen und explizit einen nicht-arg Konstruktor, oder das System nicht in der Lage sein , jeden aufruf Konstruktor ohne Argument. Ich glaube, aus diesem Grund wird empfohlen, stattdessen eine statische Factory-Methode zu verwenden - dies verringert lediglich das Risiko, dass vergessen wird, einen Konstruktor ohne Argumente zu definieren.
JHH
@JHH, das zur Kompilierungszeit selbst fehlschlägt, also kein so großes Risiko. Das Problem hierbei ist jedoch, dass die Überladung von Konstruktoren, ein wichtiges Programmierparadigma, von Android abgelehnt wird.
PS95
20

Ich bin nicht einverstanden mit yydi Antwort sagen:

Wenn Android beschließt, Ihr Fragment später neu zu erstellen, wird der Konstruktor ohne Argumente Ihres Fragments aufgerufen. Das Überladen des Konstruktors ist also keine Lösung.

Ich denke, es ist eine Lösung und eine gute, genau aus diesem Grund wurde sie von der Java-Kernsprache entwickelt.

Es ist wahr, dass Android-System Ihre zerstören und neu erstellen kann Fragment. So können Sie Folgendes tun:

public MyFragment() {
//  An empty constructor for Android System to use, otherwise exception may occur.
}

public MyFragment(int someInt) {
    Bundle args = new Bundle();
    args.putInt("someInt", someInt);
    setArguments(args);
}

Es ermöglicht Ihnen, someIntvon getArguments()letzterem an zu ziehen , selbst wenn das Fragmentvom System neu erstellt wurde. Dies ist eine elegantere Lösung als der staticKonstruktor.

Meiner Meinung nach sind staticKonstruktoren nutzlos und sollten nicht verwendet werden. Sie werden Sie auch einschränken, wenn Sie dies in Zukunft erweitern Fragmentund dem Konstruktor weitere Funktionen hinzufügen möchten . Mit dem staticKonstruktor können Sie dies nicht tun.

Aktualisieren:

Android hat eine Inspektion hinzugefügt, die alle nicht standardmäßigen Konstruktoren mit einem Fehler kennzeichnet.
Ich empfehle, es aus den oben genannten Gründen zu deaktivieren.

Ilya Gazman
quelle
4
Ein weiterer Vorteil einer statischen Methode, die ich oben nicht erwähnt habe, besteht darin, dass Sie nicht versehentlich Eigenschaften daraus festlegen können.
Yydl
4
In Bezug auf Ihren Standpunkt zum Thema "Dieses Fragment erweitern" wäre diese Methode außerdem sehr schlecht, wenn Sie die Klasse jemals erweitern würden. Wenn Sie super aufrufen, wird der Aufruf von setArguments () nur für das Kind oder das Elternteil wirksam, nicht jedoch für beide!
Yydl
2
@yydle Sie können diese Situation vermeiden, indem Sie get-Argumente aufrufen, um das untergeordnete Bundle zu initialisieren. Java übrigens immer besser.
Ilya Gazman
9
Stimmt, aber das ist ein weiterer Grund, die Leute zu ermutigen, das von Google vorgeschlagene Muster zu verwenden. Natürlich sind wir uns alle einig, dass Ihre Lösung zu 100% technisch machbar ist. Ähnlich gibt es viele Möglichkeiten, viele Dinge zu tun. Die Frage ist jedoch, ob es das Beste ist. Und ich bin der festen Überzeugung, dass die Verwendung des Konstruktors nicht die wahre Natur dessen darstellt, wie dies funktionieren soll.
Yydl
3
Ich stimme @yydl zu, dass die statische Erstellung besser ist. Ein weiterer Vorteil ist die Abhängigkeitsinjektion zukünftiger neuer Abhängigkeiten - der Konstruktor ist dafür schlecht geeignet und wird wahrscheinlich mehr Codeänderungen verursachen (oder mehr Konstruktoren hinzufügen).
Boon
19

Einige Kotlin- Codes:

companion object {
    fun newInstance(first: String, second: String) : SampleFragment {
        return SampleFragment().apply {
            arguments = Bundle().apply {
                putString("firstString", first)
                putString("secondString", second)
            }
        }
    }
}

Und Sie können Argumente damit bekommen:

val first: String by lazy { arguments?.getString("firstString") ?: "default"}
val second: String by lazy { arguments?.getString("secondString") ?: "default"}
Rafols
quelle
3

Die beste Vorgehensweise zum Instanzieren von Fragmenten mit Argumenten in Android besteht darin, eine statische Factory-Methode in Ihrem Fragment zu haben.

public static MyFragment newInstance(String name, int age) {
    Bundle bundle = new Bundle();
    bundle.putString("name", name);
    bundle.putInt("age", age);

    MyFragment fragment = new MyFragment();
    fragment.setArguments(bundle);

    return fragment;
}

Sie sollten vermeiden, Ihre Felder mit der Instanz eines Fragments festzulegen. Denn wenn das Android-System Ihr Fragment neu erstellt und das System mehr Speicher benötigt, wird das Fragment mithilfe eines Konstruktors ohne Argumente neu erstellt.

Weitere Informationen zu bewährten Methoden zum Instanziieren von Fragmenten mit Argumenten finden Sie hier.

Gunhan
quelle
2

Aufgrund der Fragen zu Best Practices möchte ich hinzufügen, dass es sehr oft eine gute Idee ist, bei der Arbeit mit einigen REST-Webdiensten einen hybriden Ansatz zum Erstellen von Fragmenten zu verwenden

Wir können keine komplexen Objekte übergeben, z. B. ein Benutzermodell, um ein Benutzerfragment anzuzeigen

Was wir aber tun können, ist, onCreatediesen Benutzer einzuchecken ! = Null und wenn nicht - dann bringen Sie ihn aus der Datenschicht, andernfalls - verwenden Sie vorhandene.

Auf diese Weise erhalten wir sowohl die Fähigkeit, im Falle einer Fragmentwiederherstellung durch Android durch userId neu zu erstellen, als auch die Schnelligkeit für Benutzeraktionen, sowie die Fähigkeit, Fragmente zu erstellen, indem wir das Objekt selbst oder nur dessen ID gedrückt halten

So etwas gefällt mir:

public class UserFragment extends Fragment {
    public final static String USER_ID="user_id";
    private User user;
    private long userId;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        userId = getArguments().getLong(USER_ID);
        if(user==null){
            //
            // Recreating here user from user id(i.e requesting from your data model,
            // which could be services, direct request to rest, or data layer sitting
            // on application model
            //
             user = bringUser();
        }
    }

    public static UserFragment newInstance(User user, long user_id){
        UserFragment userFragment = new UserFragment();
        Bundle args = new Bundle();
        args.putLong(USER_ID,user_id);
        if(user!=null){
            userFragment.user=user;
        }
        userFragment.setArguments(args);
        return userFragment;

    }

    public static UserFragment newInstance(long user_id){
        return newInstance(null,user_id);
    }

    public static UserFragment newInstance(User user){
        return newInstance(user,user.id);
    }
}
Tigra
quelle
3
Sie sagten: "Wir können keine komplexen Objekte übergeben, zum Beispiel ein Benutzermodell." - Es ist nicht wahr, wir können. So: User user = /*...*/ Setzen Sie den Benutzer in das Bundle: Bundle bundle = new Bundle(); bundle.putParcelable("some_user", user); und holen Sie den Benutzer von Argumenten ab: User user = getArguments().getParcelable("some_user"); Das Objekt muss die Paketschnittstelle implementieren. Link
Adam Varhegyi
3
Nun ja, aber wenn die Klasse komplex ist und Verweise auf andere Objekte enthält ... Ich persönlich bevorzuge es einfach zu halten, entweder ich habe ein Objekt oder ich habe es nicht und muss es dann bekommen
Tigra
1

Verwenden Sie diesen Code 100% beheben Sie Ihr Problem

Geben Sie diesen Code in firstFragment ein

public static yourNameParentFragment newInstance() {

    Bundle args = new Bundle();
    args.putBoolean("yourKey",yourValue);
    YourFragment fragment = new YourFragment();
    fragment.setArguments(args);
    return fragment;
}

Dieses Beispiel sendet boolesche Daten

und in SecendFragment

yourNameParentFragment name =yourNameParentFragment.newInstance();
   Bundle bundle;
   bundle=sellDiamondFragments2.getArguments();
  boolean a= bundle.getBoolean("yourKey");

Der Wert im ersten Fragment ist statisch

fröhlicher Code

Amin Emadi
quelle
0

Die beste Methode zum Instanziieren des Fragments ist die Verwendung der Standardmethode Fragment.instantiate oder der Factory-Methode zum Instanziieren des Fragments.
Achtung: Erstellen Sie immer einen leeren Konstruktor im Fragment eines anderen, während das Wiederherstellen des Fragmentspeichers eine Laufzeitausnahme auslöst.

Mahesh
quelle
0

Ich bin in letzter Zeit hier. Aber etwas, von dem ich gerade wusste, dass es dir ein bisschen helfen könnte.

Wenn Sie Java verwenden, gibt es nicht viel zu ändern. Aber für Kotlin-Entwickler gibt es hier einen folgenden Ausschnitt, der Sie zu einem Keller machen kann, auf dem Sie laufen können:

  • Übergeordnetes Fragment:
inline fun <reified T : SampleFragment> newInstance(text: String): T {
    return T::class.java.newInstance().apply {
        arguments = Bundle().also { it.putString("key_text_arg", text) }
    }
}
  • Normaler Anruf
val f: SampleFragment = SampleFragment.newInstance("ABC")
// or val f = SampleFragment.newInstance<SampleFragment>("ABC")
  • Sie können die übergeordnete Init-Operation in der untergeordneten Fragmentklasse erweitern um:
fun newInstance(): ChildSampleFragment {
    val child = UserProfileFragment.newInstance<ChildSampleFragment>("XYZ")
    // Do anything with the current initialized args bundle here
    // with child.arguments = ....
    return child
}

Viel Spaß beim Codieren.

vhfree
quelle
-2

setArguments()ist nutzlos. Es bringt nur ein Durcheinander.

public class MyFragment extends Fragment {

    public String mTitle;
    public String mInitialTitle;

    public static MyFragment newInstance(String param1) {
        MyFragment f = new MyFragment();
        f.mInitialTitle = param1;
        f.mTitle = param1;
        return f;
    }

    @Override
    public void onSaveInstanceState(Bundle state) {
        state.putString("mInitialTitle", mInitialTitle);
        state.putString("mTitle", mTitle);
        super.onSaveInstanceState(state);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {
        if (state != null) {
            mInitialTitle = state.getString("mInitialTitle");
            mTitle = state.getString("mTitle");
        } 
        ...
    }
}
Vadim Star
quelle
Es sei denn, Sie wurden gerade gezwungen, eine weitere Methode zu überschreiben und ein Feld zu erstellen, das für den onViewCreatedBereich isoliert sein könnte . Ich denke, es ist praktisch, viele Möglichkeiten, dasselbe zu tun. Es ist auch eine einfache Möglichkeit, nach vom Benutzer vorgenommenen Aktualisierungen zu getArgumentsonSaveInstanceState
suchen
@Asagen, ich mag Ihren Kommentar zum Vergleichen von Anfangs- und Benutzerwerten. Ich habe Code bearbeitet und bin der Meinung, dass er immer noch einheitlich und klar ist getArguments. Was ist mit dem onViewCreatedUmfang ... Wir können dort das Statusbündel wiederherstellen. Aber ich ziehe es einfach vor, onCreateViewleicht und schnell zu machen und alle umfangreichen Initialisierungen innerhalb eines zu machen, onActivityCreatedweil ich Fragment.getActivity()manchmal gerne zurückkehren möchte nullund weil onAttach()Änderungen in der neuen Version von API 23 vorgenommen wurden.
Vadim Star
Alles hast du hier war unterwegs set und get Argumentsin saveInstanceState. Sie tun im Wesentlichen das Gleiche wie "unter der Haube"
OneCricketeer
1
@ Cricket_007 oder genau gegenüber . Verwendung saveInstanceStateist "unter der Haube". Und die Verwendung von Argumentsist eine Verdoppelung der Funktionalität, mit der Sie überprüfen: zuerst ArgumentsWerte und dann saveInstanceStateWerte. Weil du es saveInstanceStateirgendwie benutzen musst . Was ist mit Arguments... sie sind nicht notwendig.
Vadim Star
Argumente entsprechen den Intent-Extras für Fragmente. Sie sind nicht nutzlos, sie enthalten die vom aktuellen Zustand abweichenden Anfangsparameter.
BladeCoder
-12

Ich glaube, ich habe eine viel einfachere Lösung dafür.

public class MyFragment extends Fragment{

   private String mTitle;
   private List<MyObject> mObjects;

   public static MyFragment newInstance(String title, List<MyObject> objects)
   MyFragment myFrag = new MyFragment();
   myFrag.mTitle = title;
   myFrag.mObjects = objects;
   return myFrag;
   }
Stefan Bogaard
quelle
12
mObjects werden gelöscht, wenn MyFragment neu erstellt wird (der Benutzer wechselt zum Startbildschirm des Geräts und öffnet später die App, die bei MyFragment aufgehört hat). Sie können mObjects beibehalten, indem Sie MyFragment ein Bundle als Argumente senden.
Ynnadkrap
1
Wie greift die statische Methode auf nicht statische Elementvariablen zu?
OrhanC1
2
@ynnadkrap Sie haben Recht, die Verwendung eines Bundles ist der richtige Weg, um hierher zu gelangen.
Stefan Bogaard
2
@ OrhanC1 Gemäß diesem Beispielcode greift die statische Methode nicht auf die Mitgliedsvariablen zu. Die Instanz von MyFragment greift auf ihre Mitglieder zu. Hier liegt kein Fehler vor. Ich empfehle diese Antwort jedoch niemandem, denn wenn Ihr Fragment aus dem Speicher entfernt wird, um vom Android-Betriebssystem etwas Speicherplatz freizugeben, wird dieses Fragment nach dem Neustart der Aktivität mit dem leeren Standardkonstruktor erstellt, ohne Ameisenvariablen zuzuweisen.
Gunhan
@ Gunhan Du hast recht! Es ist nicht. Entschuldigung für die Verwirrung :)
OrhanC1