Was ist der Vorteil der Verwendung von Fragmenten in Android anstelle von Ansichten?

102

Bei der Entwicklung für Androidkönnen Sie Ihr Ziel (oder Minimum) sdk auf 4 (API 1.6) setzen und das Android-Kompatibilitätspaket (v4) hinzufügen, um Unterstützung für hinzuzufügen Fragments. Gestern habe ich dies getan und erfolgreich implementiert Fragments, um Daten aus einer benutzerdefinierten Klasse zu visualisieren.

Meine Frage lautet: Was ist der Nutzen für die Verwendung Fragments im Gegensatz zum einfachen Abrufen einer Ansicht von einem benutzerdefinierten Objekt und der Unterstützung von API 1.5?

Angenommen, ich habe die Klasse Foo.java:

public class Foo extends Fragment {

    /** Title of the Foo object*/
    private String title;
    /** A description of Foo */
    private String message;

    /** Create a new Foo
     * @param title
     * @param message */
    public Foo(String title, String message) {
        this.title = title;
        this.message = message;
    }//Foo

    /** Retrieves the View to display (supports API 1.5. To use,
     * remove 'extends Fragment' from the class statement, along with
     * the method {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}) 
     * @param context Used for retrieving the inflater */
    public View getView(Context context) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View v = inflater.inflate(R.layout.foo, null);
        TextView t = (TextView) v.findViewById(R.id.title);
        t.setText(this.title);
        TextView m = (TextView) v.findViewById(R.id.message);
        m.setText(this.message);
        return v;
    }//getView 

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (container == null) {
            return null;
        }
        View v = inflater.inflate(R.layout.foo, null);
        TextView t = (TextView) v.findViewById(R.id.title);
        t.setText(this.title);
        TextView m = (TextView) v.findViewById(R.id.message);
        m.setText(this.message);
        return v;
    }//onCreateView

}//Foo

Beide Methoden sind sehr einfach zu erstellen und in einer Aktivität zu bearbeiten, die List<Foo>beispielsweise angezeigt werden muss (z. B. programmgesteuert zu a hinzugefügt wird ScrollView). Sie sind also Fragmentswirklich nützlich oder nur eine überglorifizierte Vereinfachung von Eine Ansicht erhalten, z. B. über den obigen Code?

Phil
quelle
2
Fragmente müssen keine Benutzeroberfläche haben, sie können nur wiederverwendbares Verhalten sein. Eine Ansicht wäre in diesem Fall redundant.
Philipp Reichart
Ich habe dies in einer anderen Frage beantwortet. Siehe stackoverflow.com/a/14912608/909956 T; dr - Manchmal können Sie mit Fragmenten mehr wiederverwendbare Komponenten erstellen, als sich auf die Implementierung einer benutzerdefinierten Ansicht zu verlassen. Siehe den Link für warum.
Numan Salati

Antworten:

172

Der Hauptgrund für die Verwendung von Fragmenten liegt in den Backstack- und Lebenszyklusfunktionen. Andernfalls sind benutzerdefinierte Ansichten leichter und einfacher zu implementieren.

Zuerst habe ich tatsächlich versucht, eine Telefon- / Tablet-App mit benutzerdefinierten Ansichten zu erstellen. Alles schien über Telefone UND Tablets hinweg zu funktionieren, sogar der Wechsel von einem einzelnen Panel zu einem geteilten Panel. Ich hatte Probleme mit dem Zurück-Knopf und dem Lebenszyklus. Da ich Ansichten einfach manuell aktualisierte ... gab es nichts, was die Geschichte der Ansichten und ihre Zustände verfolgte. Daher funktionierte die Zurück-Schaltfläche nicht wie erwartet und es war schwierig, selbst den neuesten Status während Lebenszyklusereignissen wiederherzustellen, z. B. beim Drehen der App. Um dies zu beheben, musste ich meine benutzerdefinierten Ansichten in Fragmente einschließen und den FragmentManager verwenden, damit die vorherigen Status gespeichert und neu erstellt wurden.

Nachdem ich geantwortet hatte, stellte ich fest, dass ich ein Jahr zuvor eine ähnliche Frage gestellt hatte: https://stackoverflow.com/a/11126397/618881

Henry
quelle
14
Sehr gute Antwort. Ich wollte nur hinzufügen, dass Fragmente seit 4.2 oder Support Library Rev 11 verschachtelt werden können.
Kar
2
Danke @Karlo für das Update. Ich hielt es konzeptionell nicht für möglich, aber sie haben es mithilfe eines privaten FragmentManagers über getChildFragmentManager () umgangen. Oh, und es ist API 17, nicht 11, und über die Support-Bibliothek erhältlich.
Henry
2
Ich habe mir diese Frage gerade noch einmal angesehen und auch meine Erfahrung hat sich geändert. Dies ist eine Antwort, die ein gutes Verständnis der Vor- und Nachteile bietet und sehr hilfreich ist. Vielen Dank!
Phil
2
Willst du +1 diese Antwort, aber das würde die aktuelle Punktzahl ruinieren. Außerdem ist 70 nicht meine Lieblingsnummer.
Behnam
1
Im letzten Jahr dachte ich auch, dass Fragmente keine außergewöhnlichen Funktionen bieten, aber ich habe festgestellt, dass ich nach dem Zurückklicken auf die Aktivität alle darin heruntergeladenen Bilder verloren habe und daher die Cache-Implementierung hinzufügen musste, jetzt denke ich darüber nach Fragmente kann es sehr einfach sein
Shirish Herwade
27

Ich würde sagen, Fragmente sind in zwei Szenarien nützlich: Wenn Sie Ansichten auf einigen Geräten / Ausrichtungen aufteilen und sie in zwei Aktivitäten anzeigen und den gesamten Inhalt in einem auf anderen Geräten anzeigen. Dies wäre ein Anwendungsfall, wenn Sie auf einem Tablet oder sogar im Querformat auf einem Telefon arbeiten: z. B. zeigen Sie die Liste der Elemente und die Details auf einem Bildschirm an. Auf einem Telefon oder im Hochformat zeigen Sie nur einen Teil.

Ein weiterer Anwendungsfall sind wiederverwendbare Ansichten. Wenn Sie also einige Ansichten haben, die für verschiedene Aktivitäten sichtbar sind, und auch einige Aktionen ausführen, können Sie dieses Verhalten in ein Fragment einfügen und dann wiederverwenden. Natürlich könnten Sie das wahrscheinlich auch mit benutzerdefinierten Widgets tun.

Ich würde keinen Grund sehen, Fragmente für jede Ansicht zu verwenden, und ich denke, es wäre nur ein Overhead. Ich benutze sie nur im ersten Anwendungsfall und ich würde hier sagen, es ist eine Vereinfachung.

Maria Neumayer
quelle
Danke, das war auf jeden Fall hilfreich. Ich denke, ich werde mich an Ansichten halten und meinen eigenen "Back Stack" erstellen, um sie wiederverwendbar zu machen.
Phil
3

Android führte Fragmente in Android 3.0 (API-Level 11) ein, hauptsächlich um dynamischere und flexiblere UI-Designs auf großen Bildschirmen wie Tablets zu unterstützen. Da der Bildschirm eines Tablets viel größer als der eines Mobilteils ist, gibt es mehr Platz zum Kombinieren und Austauschen von UI-Komponenten. Fragmente ermöglichen solche Designs, ohne dass Sie komplexe Änderungen an der Ansichtshierarchie verwalten müssen. Durch Aufteilen des Layouts einer Aktivität in Fragmente können Sie das Erscheinungsbild der Aktivität zur Laufzeit ändern und diese Änderungen in einem von der Aktivität verwalteten Backstack beibehalten.

Hier können Sie mehr lesen.

Yury
quelle
Ich habe die gesamte Dokumentation gelesen, suchte jedoch nach etwas, das ihren Nutzen besser erklärt, z. B. für Tablets oder den Backstack
Phil
3
  1. Aufgeteilter Bildschirm für Szenarioaktivität - Wir haben ein Layout und eine Aktivität, die den linken rechten Bildschirmteil behandeln
  2. Szenario FragmentActivity Wir haben ein Layout für den Hauptbildschirm, eines für links und eines für rechts

Szenario eins ist gut, wenn Sie eine einfache Anwendung haben.

Szenario zwei ist gut, wenn Sie mehrere Fragmente und mehrere FragmentActivities haben möchten und diese kombinieren können. Sie können auch zwischen Fragmenten interagieren.

Ich habe Split Screen Fragmentactivity Ich kann es mit 'Intent Extras' aufrufen und fragmentActivity mitteilen, welches Fragment geladen werden soll. Fragmente sind gut, weil sie nicht manifest sind, sodass Sie wiederverwendbare Fragmente und FragmentActvity erstellen können.

Aber es macht Ihr Projekt größer. Wenn Sie jedoch ein großes Projekt erstellen, können Sie viele speichern. Weil Sie dieselben Fragmente oder dieselbe Fragmentaktivität verwenden können.

Und ich denke, dass diese Fragmente etwas spät kommen, also müssen Sie versuchen, auf neue Weise zu denken. Versuchen Sie vielleicht einfach, Ihre Aktivität in FragmentActivity zu konvertieren. Versuchen Sie später, wiederverwendbaren Code zu finden und daraus ein Fragment zu erstellen.

Es ist nützlich, aber ich weiß nicht wie im Moment. Aber ich habe einige Ideen.

Das ist immer ein Problem. Das Android-Team hat etwas gedacht und niemand weiß, wofür es gut ist. Weil wir kaum so lernen wie es war und hier kommen einige neue Dinge.

Meiner Meinung nach ist es gut, aber nicht aus gutem Grund, dass Google es uns sagt.

Mertuarez
quelle
0

Fügen Sie einen Fall hinzu, wenn Sie Fragment oder Aktivität über CustomView verwenden:

Wenn Sie CursorLoader verwenden, um bestimmte Ansichten, ListView oder TextView zu beobachten, und deren Anzeigewert aktualisieren möchten, wenn die Daten Ihres ContentProviders im Back-End aktualisiert werden (im häufigsten Fall haben Sie einen Dienst, der Ihre lokale Datenbank aktualisiert, indem Sie regelmäßig Daten aus der entfernten Datenbank / Cloud abrufen )

macio.Jun
quelle
-2

Eine große Sache, die in den obigen Kommentaren nicht erwähnt wird, ist, dass ein Fragment im Speicher verbleibt, selbst wenn Android die Aktivität beendet und sie neu startet, wenn Sie beispielsweise die Ausrichtung Ihres Geräts ändern. Dies geschieht aus Leistungsgründen, kann aber auch zu unerwarteten Ergebnissen führen, wenn Sie damit gerechnet haben, dass Fragmente zerstört werden, nur um festzustellen, dass sie aus dem Nichts neu erstellt werden.

AndroidDev
quelle