Dilemma: Wann sollten Fragmente oder Aktivitäten verwendet werden?

786

Ich weiß, dass Activitiessie einen einzelnen Bildschirm meiner Anwendung darstellen sollen, während Fragmentssie als wiederverwendbare UI-Layouts mit darin eingebetteter Logik konzipiert sind.

Bis vor kurzem habe ich eine Anwendung entwickelt, die besagt, dass sie entwickelt werden sollte. Ich habe ein erstellt Activity, um einen Bildschirm meiner Anwendung darzustellen, und Fragmente für ViewPageroder verwendet Google Maps. Ich habe selten eine ListFragmentoder andere Benutzeroberfläche erstellt, die mehrmals wiederverwendet werden kann.

Kürzlich bin ich auf ein Projekt gestoßen, das nur 2 enthält, Activitieseines ist ein SettingsActivityund das andere ist das MainActivity. Das Layout der MainActivityist mit vielen versteckten Vollbild-UI-Fragmenten gefüllt und nur eines wird angezeigt. In der ActivityLogik gibt es viele FragmentTransitionszwischen den verschiedenen Bildschirmen der Anwendung.

Was mir an diesem Ansatz gefallen hat, ist, dass die Anwendung, da sie eine verwendet ActionBar, intakt bleibt und sich nicht mit der Bildschirmwechselanimation bewegt, was beim ActivityUmschalten der Fall ist . Dies verleiht diesen Bildschirmübergängen ein flüssigeres Gefühl.

Ich denke, ich bitte Sie, Ihre aktuelle Entwicklungsweise zu diesem Thema mitzuteilen. Ich weiß, dass es auf den ersten Blick wie eine meinungsbasierte Frage aussehen könnte, aber ich betrachte es als eine Frage zu Android-Design und -Architektur ... Nicht wirklich eine Meinungsbasierte.

UPDATE (01.05.2014): Nach dieser Präsentation von Eric Burke von Square (was ich sagen muss, ist eine großartige Präsentation mit vielen nützlichen Tools für Android-Entwickler. Und ich bin in keiner Weise mit Square verwandt).

http://www.infoq.com/presentations/Android-Design/

Aus meiner persönlichen Erfahrung in den letzten Monaten habe ich herausgefunden, dass der beste Weg, meine Anwendungen zu erstellen, darin besteht, Gruppen von Fragmenten zu erstellen, die einen Fluss in der Anwendung darstellen und alle diese Fragmente in einem präsentieren Activity. Sie haben also im Grunde die gleiche ActivitiesAnzahl von Flows in Ihrer Anwendung wie die Anzahl der Flows. Auf diese Weise bleibt die Aktionsleiste auf allen Bildschirmen des Flusses intakt, wird jedoch beim Ändern eines Flusses neu erstellt, was sehr sinnvoll ist. Wie Eric Burke feststellt und wie ich auch festgestellt habe, ist die Philosophie, so wenig Activitieswie möglich zu verwenden, nicht für alle Situationen anwendbar, da sie die von ihm als "Gott" bezeichnete Aktivität durcheinander bringt.

Emil Adz
quelle
2
Schauen Sie sich meinen Beitrag unter SO - stackoverflow.com/questions/24647078/…
My God

Antworten:

271

Experten werden Ihnen sagen: "Wenn ich die Benutzeroberfläche sehe, weiß ich, ob ich ein Activityoder ein verwenden soll Fragment". Am Anfang wird dies keinen Sinn haben, aber mit der Zeit werden Sie tatsächlich erkennen können, ob Sie es brauchen Fragmentoder nicht.

Es gibt eine gute Praxis, die ich für mich sehr hilfreich fand. Es kam mir in den Sinn, als ich versuchte, meiner Tochter etwas zu erklären.

Stellen Sie sich nämlich eine Box vor, die einen Bildschirm darstellt. Können Sie einen anderen Bildschirm in dieses Feld laden? Wenn Sie eine neue Box verwenden, müssen Sie mehrere Elemente aus der ersten Box kopieren? Wenn die Antwort Ja lautet, sollten Sie verwenden Fragments, da der Stamm Activityalle duplizierten Elemente enthalten kann, um Zeit beim Erstellen zu sparen, und Sie einfach Teile der Box ersetzen können.

Vergessen Sie aber nicht, dass Sie immer einen Kastenbehälter ( Activity) benötigen, sonst werden Ihre Teile verteilt. Also eine Box mit Teilen drinnen.

Achten Sie darauf, die Box nicht zu missbrauchen. Android UX-Experten raten (Sie finden sie auf YouTube), wann wir explizit eine andere laden sollten Activity, anstatt eine zu verwenden Fragment(wie wenn wir uns mit der Navigationsleiste befassen, die Kategorien hat). Sobald Sie sich wohl fühlen Fragments, können Sie alle ihre Videos ansehen. Noch mehr sind sie Pflichtmaterial.

Können Sie sich jetzt Ihre Benutzeroberfläche ansehen und herausfinden, ob Sie eine Activityoder eine benötigen Fragment? Hast du eine neue Perspektive bekommen? Ich denke du hast es getan.

Sandale
quelle
4
Hast du einen Link zu dem von dir erwähnten Youtube-Feed? Ich suche nach "Android UX-Experten" und "Android UX", bin mir aber nicht ganz sicher, über welche Videos Sie sprechen.
Ich
2
Nicht mehr, habe es vor über einem Jahr gesehen. Suche nach Android Entwickler offiziell über UX
Sandalone
1
Ein Beispiel für eine Überlegung: Aktivität hat parentActivity, sodass wir den Backstack synthetisieren können, während wir von der Benachrichtigung aus eingeben, aber ich glaube nicht, dass es ein solches parentFragment gibt.
fikr4n
@BornToCode gibt es getParentFragment: developer.android.com/reference/android/support/v4/app/...
ToolmakerSteve
@ToolmakerSteve ja, es ist getParentFragment, aber es ist nicht das, was ich meinte, Alter, siehe developer.android.com/guide/topics/manifest/…
fikr4n
129

Meine Philosophie lautet:

Erstellen Sie eine Aktivität nur, wenn dies unbedingt erforderlich ist. Mit dem Backstack, der für das Festschreiben einer Reihe von Fragmenttransaktionen zur Verfügung gestellt wird, versuche ich, so wenig Aktivitäten wie möglich in meiner App zu erstellen. Außerdem ist die Kommunikation zwischen verschiedenen Fragmenten viel einfacher als das Hin- und Herschicken von Daten zwischen Aktivitäten.

Aktivitätsübergänge sind teuer, oder? Zumindest glaube ich das - da die alte Aktivität zerstört / angehalten / gestoppt, auf den Stapel geschoben und dann die neue Aktivität erstellt / gestartet / fortgesetzt werden muss.

Es ist nur meine Philosophie, seit Fragmente eingeführt wurden.

VJ Vélan Solutions
quelle
2
stimmt, aber wie Sie geschrieben haben, ist es manchmal erforderlich, Aktivitäten zu verwenden. Ein Beispiel ist ein Kamerabildschirm, auf dem es besser ist, ihn im Querformat zu verwenden. Ein weiteres Beispiel ist der Konfigurationsbildschirm, der angezeigt wird, wenn Sie ein benutzerdefiniertes appWidget (auf dem "Desktop" - der Launcher-App) platzieren.
Android-Entwickler
Vielen Dank für Ihre Antwort und das Teilen Ihrer Erfahrungen. Sie denken also, dass es in Android eine gute Praxis ist, die Anwendung auf eine Aktivität zu beschränken und Fragment für alle Bildschirme zu verwenden, wenn die Anwendungsarchitektur dies zulässt?
Emil Adz
1
Wie lösen Sie dann das Problem, dass Fragmente sich gegenseitig "Zustand" übergeben müssen? Der gesamte Status aller Fragmente muss in einer Aktivität leben, andernfalls müssen Sie einen Singleton verwenden.
Mr_E
36
Ich bin nicht davon überzeugt, dass die Kommunikation zwischen verschiedenen Fragmenten viel einfacher ist, als Daten zwischen Aktivitäten hin und her zu senden.
Denny
3
Zumindest onActivityResult()ist es sicherer und einfacher als die Rückrufe von Fragmenten.
CoolMind
59

Nun, laut Googles Vorträgen (vielleicht hier , ich erinnere mich nicht) sollten Sie in Betracht ziehen, Fragmente zu verwenden, wann immer dies möglich ist, da dies die Wartung und Kontrolle Ihres Codes erleichtert.

Ich denke jedoch, dass es in einigen Fällen zu komplex werden kann, da die Aktivität, die die Fragmente hostet, zwischen ihnen navigieren / kommunizieren muss.

Ich denke, Sie sollten selbst entscheiden, was für Sie am besten ist. Es ist normalerweise nicht so schwer, eine Aktivität in ein Fragment umzuwandeln und umgekehrt.

Ich habe einen Beitrag über diese dillema erstellt hier , wenn Sie etwas weiter lesen möchten.

Android-Entwickler
quelle
5
Vielen Dank für Ihre Antwort und das Teilen Ihrer Erfahrungen. Sie denken also, dass es in Android eine gute Praxis ist, die Anwendung auf eine Aktivität zu beschränken und Fragment für alle Bildschirme zu verwenden, wenn die Anwendungsarchitektur dies zulässt?
Emil Adz
Dies hängt vom Projekt ab. Wenn es Ihnen jedoch zu kompliziert wird, können Sie auch mehrere Aktivitäten durchführen. Haben Sie keine Angst, eine der Methoden anzuwenden. Sie können auch beide verwenden. Vielleicht ist es manchmal zu schwierig für Sie, Fragmente anstelle von Aktivitäten zu verwenden. Ich denke, Sie sollten versuchen, Fragmente zu verwenden, aber zwingen Sie es nicht, überall zu sein, wenn es Ihnen zu viel im Weg steht ...
Android-Entwickler
Was ist, wenn ich möchte, dass dieser Effekt der ActionBar erhalten bleibt und der gesamte Inhalt gewechselt wird? Ist es möglich, dies mit Aktivitäten zu erreichen?
Emil Adz
27

Warum ich in ALLEN FÄLLEN Fragment gegenüber Aktivität bevorzuge.

  • Aktivität ist teuer. In Fragment werden Ansichten und Eigenschaftszustände getrennt. Wenn sich ein Fragment befindet backstack, werden seine Ansichten zerstört. Sie können also viel mehr Fragmente als Aktivität stapeln.

  • BackstackManipulation. Mit FragmentManagerist es einfach, alle Fragmente zu löschen, mehr einzufügen als auf Fragmenten und etcs. Aber für Activity wird es ein Albtraum sein, diese Dinge zu manipulieren.

  • Ein viel vorhersehbarer Lebenszyklus . Solange die Host-Aktivität nicht recycelt wird. Die Fragmente im Backstack werden nicht recycelt. Es ist also möglich, ein FragmentManager::getFragments()bestimmtes Fragment zu finden (nicht empfohlen).

Qylin
quelle
HI, ich habe Ihre Rezension über die Vorteile von Frag gegenüber Act gelesen. Haben Sie ein Projekt, das dasselbe in Ihrem Github Repo zeigt?
Ümañg ßürmån
24

Seit Jetpack ist die Single-Activity-App die bevorzugte Architektur. Besonders nützlich mit der Navigationsarchitekturkomponente .

Quelle

Francis
quelle
Danke dafür!
Simão Garcia
1
Ich habe heute zum ersten Mal über Jetpack gelesen. :) Wir erstellen Apps für einzelne Aktivitäten, seit Fragmente eingeführt wurden. Multiaktivität ist viel komplizierter.
Der unglaubliche
1
@TheincredibleJan Sie haben Recht, Single Activity App Architektur war eine bessere Lösung lange vor Jetpack
Francis
12

Meiner Meinung nach ist es nicht wirklich relevant. Der zu berücksichtigende Schlüsselfaktor ist

  1. Wie oft werden Sie Teile der Benutzeroberfläche (z. B. Menüs) wiederverwenden?
  2. ist die App auch für Tablets?

Fragmente werden hauptsächlich zum Erstellen von Mehrbereichsaktivitäten verwendet, wodurch sie sich perfekt für auf Tablets / Telefone reagierende Apps eignen.

Isaac Urbina
quelle
Ich würde sagen, dass Fragmente hauptsächlich dazu verwendet werden, benutzerdefinierte Ansichten zu erstellen, ohne sie als benutzerdefinierte Ansichten zu betrachten. das passiert sowieso. Fragmente, die wir ursprünglich von Google gezeigt haben, sind eine praktische Möglichkeit, auf Tablets ansprechende Apps zu erstellen, sodass Sie sie bei Bedarf in verschiedene Aktivitäten einbinden können. Eine Möglichkeit, Code mehr oder weniger an eine Ansicht anzuhängen und sie an der gewünschten Stelle anzubringen (ohne benutzerdefinierte Ansichten zu erstellen).
Lassi Kinnunen
11

Vergessen Sie nicht, dass eine Aktivität der Block / die Komponente einer Anwendung ist, die über Intent freigegeben und gestartet werden kann! Daher sollte jede Aktivität in Ihrer Anwendung nur eine Art von Aufgabe lösen. Wenn Sie nur eine Aufgabe in Ihrer Anwendung haben, benötigen Sie meiner Meinung nach nur eine Aktivität und bei Bedarf viele Fragmente. Natürlich können Sie Fragmente in zukünftigen Aktivitäten wiederverwenden, die andere Aufgaben lösen. Dieser Ansatz wird eine klare und logische Aufgabentrennung sein. Und Sie müssen nicht eine Aktivität mit unterschiedlichen Intent-Filterparametern für unterschiedliche Sätze von Fragmenten verwalten. Sie definieren Aufgaben in der Entwurfsphase des Entwicklungsprozesses basierend auf den Anforderungen.

Gast
quelle
In unseren Anwendungen besteht die eine Art der Aufgabe der Aktivität darin, die Navigationsschublade zu halten, um die verschiedenen Fragmente einzugeben. :) Warum sollte ich mich mit Absichten für Fragmente auseinandersetzen? Es ist klar und logisch, einen statischen Verweis auf eine "globale" Datenklasse für globale Daten zu speichern und einige Werte an eine Methode zum Erstellen von Instanzen eines Fragments zu übergeben.
Der unglaubliche
9

Es gibt mehr als Sie denken, Sie müssen sich daran erinnern, dass eine Aktivität, die gestartet wird, die aufrufende Aktivität nicht implizit zerstört. Natürlich können Sie es so einrichten, dass Ihr Benutzer auf eine Schaltfläche klickt, um zu einer Seite zu gelangen. Sie starten die Aktivität dieser Seite und zerstören die aktuelle Seite. Dies verursacht viel Overhead. Der beste Leitfaden, den ich Ihnen geben kann, ist:

** Starten Sie eine neue Aktivität nur, wenn es sinnvoll ist, die Hauptaktivität und diese gleichzeitig zu öffnen (denken Sie an mehrere Fenster).

Ein gutes Beispiel dafür, wann es sinnvoll ist, mehrere Aktivitäten durchzuführen, ist Google Drive. Die Hauptaktivität bietet einen Datei-Explorer. Wenn eine Datei geöffnet wird, wird eine neue Aktivität gestartet, um diese Datei anzuzeigen. Sie können auf die Schaltfläche "Letzte Apps" klicken, um zum Browser zurückzukehren, ohne das geöffnete Dokument zu schließen, und dann möglicherweise sogar ein anderes Dokument parallel zum ersten zu öffnen.

TheHebrewHammer
quelle
Betreff "Starten Sie eine neue Aktivität nur, wenn es sinnvoll ist, die Hauptaktivität und diese gleichzeitig zu öffnen (denken Sie an mehrere Fenster)." Das glaube ich nicht. Diese Situation ist mit Fragmenten attach / detachMethoden gut gelöst .
ToolmakerSteve
7

Was ich getan habe: Wenn möglich weniger Fragment verwenden. Leider ist es in fast allen Fällen möglich. Am Ende habe ich viele Fragmente und ein paar Aktivitäten. Einige Nachteile, die ich erkannt habe:

  • ActionBar& Menü: Wenn 2 Fragmente unterschiedliche Titel und Menüs haben,
    ist dies schwer zu handhaben. Beispiel: Wenn Sie ein neues Fragment hinzufügen, können Sie den Titel der Aktionsleiste ändern. Wenn Sie ihn jedoch öffnen, können Sie backstackden alten Titel nicht wiederherstellen. Möglicherweise benötigen Sie in diesem Fragment in jedem Fragment eine Symbolleiste, aber glauben Sie mir, das wird Sie mehr Zeit verbringen.
  • Wenn wir brauchen startForResult, hat Aktivität, Fragment aber nicht.
  • Standardmäßig gibt es keine Übergangsanimation

Meine Lösung hierfür ist die Verwendung einer Aktivität, um ein Fragment darin zu verpacken . Wir haben also eine separate Aktionsleiste, ein Menü startActivityForResult, eine Animation, ...

Ich liebe Codierung
quelle
1
Sehr nützliche Punkte, danke. Können Sie " eine Aktivität zum Umschließen eines Fragments " erläutern ? Haben Sie für jedes Fragment eine eigene Aktivität erstellt? Wenn ja, brauchen Sie überhaupt Fragment?
ToolmakerSteve
3
Es gibt eine Möglichkeit, Titel und andere Dinge wiederherzustellen. verwendengetSupportFragmentManager().addOnBackStackChangedListener diese Option, um einen Listener hinzuzufügen. Holen Sie sich das aktuelle Fragment in diesen Listener und setzen Sie dann Titel und so.
Babay
4

Der einzige große Vorteil einer fragmentÜberaktivität besteht darin, dass der für Fragmente verwendete Code für verschiedene Aktivitäten verwendet werden kann. Daher bietet er die Wiederverwendbarkeit von Code in der Anwendungsentwicklung.

Sanchit Bhasin
quelle
3
Wie? Könnten Sie bitte ein Beispiel nennen?
sofs1
1
@ sofs1 Deine Frage macht nicht viel Sinn. Jeder Code in einem Fragment bleibt derselbe, unabhängig davon, von welcher Aktivität das Fragment initiiert wird.
Der unglaubliche
@TheincredibleJan Aber können wir nicht auch sagen "Jeder Code in einer Aktivität bleibt derselbe, unabhängig davon, von welcher Aktivität die zweite Aktivität instanziiert wird."? Ich sehe den Unterschied nicht.
iforce2d
3

eine Aktivität pro Anwendung verwenden Basis für bereitzustellen fragment Verwendung fragmentfür Bildschirm, fragmentsist lite Gewicht im Vergleich zu activites Fragmenten sind wieder verwendbar Fragmente werden besser geeignet für die Anwendung , die sowohl Telefon & Tablette unterstützen

varg
quelle
2

Sie können eine davon verwenden.
Grundsätzlich müssen Sie bewerten, welches für Ihre App am besten geeignet ist. Überlegen Sie, wie Sie den Geschäftsablauf verwalten und wie Sie Dateneinstellungen speichern / verwalten.

Überlegen Sie, wie Fragmente Mülldaten speichern. Wenn Sie das Fragment implementieren, müssen Sie einen Aktivitätsstamm mit Fragmenten füllen. Wenn Sie also versuchen, viele Aktivitäten mit zu vielen Fragmenten zu implementieren, müssen Sie die Leistung Ihrer App berücksichtigen, da Sie zwei Kontextlebenszyklen manipulieren (grob gesprochen), und sich an die Komplexität erinnern.

Denken Sie daran: Soll ich Fragmente verwenden? Warum sollte ich nicht?

Grüße.

Franklin Hirata
quelle
1

Ich benutze Fragmente für eine bessere Benutzererfahrung. Wenn Sie beispielsweise eine Schaltfläche haben und einen Webservice ausführen möchten, wenn Sie darauf klicken, füge ich der übergeordneten Aktivität ein Fragment hinzu.

if (id == R.id.forecast) {

    ForecastFragment forecastFragment = new ForecastFragment();
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    ft.replace(R.id.main_content, forecastFragment);
    ft.addToBackStack("backstack");
    forecastFragment.setArguments(b);
    ft.commit();
}

Auf diese Weise muss der Benutzer keine andere Aktivität ausführen.

Und zweitens bevorzuge ich Fragmente, weil man sie während der Rotation leicht handhaben kann.

Das Ö
quelle
Was macht dieses Beispiel zu einer besseren Benutzererfahrung? Woher wissen sie (oder kümmern sie sich), dass sie eine Aktivität oder ein Fragment ausführen?
iforce2d
1

Es kommt darauf an, was Sie wirklich bauen wollen. Zum Beispiel navigation drawerverwendet das Fragmente. Tabs werden ebenfalls verwendet fragments. Eine andere gute Implementierung ist, wo Sie eine haben listview. Wenn Sie das Telefon drehen und auf eine Zeile klicken, wird die Aktivität in der verbleibenden Hälfte des Bildschirms angezeigt. Persönlich benutze ich fragmentsund fragment dialogs, da es professioneller ist. Außerdem lassen sie sich leichter drehen.

Das Ö
quelle