Koordinatorlayout mit Symbolleiste in Fragmenten oder Aktivitäten


94

Mit der neuen Designbibliothek gibt es mehrere neue Layouts, die das Verhalten der Symbolleiste stark verändern, wenn der Entwickler dies wünscht. Da verschiedene Fragmente unterschiedliche Verhaltensweisen und Ziele haben, z. B. ein Galeriefragment mit einer reduzierten Symbolleiste, die ein wichtiges Foto anzeigt, oder ein Fragment ohne Bildlaufansicht, für das das Appbarlayout zum Ausblenden der Symbolleiste nicht erforderlich ist, kann eine einzige Symbolleiste in der Aktivität vorhanden sein sich als schwierig erweisen.

Sollte ich damit die Symbolleiste auf jedes Fragment verschieben? In diesem Fall muss ich die supportActionBar jedes Mal festlegen, wenn ich ein Fragment zeige, und außerdem eine Referenz der Aktivität in dem Fragment haben, die die Unabhängigkeit von Fragmenten aufhebt. Wenn ich die Symbolleiste in der Aktivität in Ruhe lasse, müssen für jeden Verhaltenstyp in jedem Fragment mehrere Layouts definiert sein. Was wäre der beste Ansatz?


1
Hallo, hast du eine Lösung gefunden?
SERG

2
Für mein aktuelles Projekt habe ich mich entschieden, bei der Symbolleiste in der Aktivität zu bleiben und bei Bedarf die richtigen Animationen zu erstellen. Aber es ist ein bisschen verworren. Ich habe versucht, die Symbolleiste in jedem Fragment zu verwenden, und es funktioniert einwandfrei, aber das Animieren der Symbolleiste zwischen Fragmentübergängen ist schwieriger und ich weiß nicht einmal, ob dies möglich ist, da ich nicht viel Erfahrung mit Animationen von Fragmentübergängen habe.
mobilepotato7

Gibt es jetzt Updates oder bessere Lösungen dafür?
Sagar Nayak

Antworten:


56

Für mich klingt es zu seltsam, in jedem Fragment eine App- und Symbolleiste zu haben. Daher habe ich mich für eine einzelne App-Leiste mit Symbolleiste in Aktivität entschieden.

Um dieses Problem mit CoordinatorLayout zu lösen, müssen Sie ein anderes Verhalten Ihres FrameLayout(oder eines anderen Layouts) festlegen , das Fragmente von jedem Fragment enthalten soll, das Sie als Standardverhalten überschreiben möchten.

Nehmen wir an, dass Ihr Standardverhalten ist app:layout_behavior="@string/appbar_scrolling_view_behavior"

Dann haben Sie in Ihrer fragment_activity_layout.xml möglicherweise Folgendes:

<android.support.design.widget.CoordinatorLayout
    android:id="@+id/coordinator"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/dashboard_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/AppTheme.Toolbar"
            app:layout_scrollFlags="scroll|enterAlways"/>
    </android.support.design.widget.AppBarLayout>

    <FrameLayout
        android:id="@+id/dashboard_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>

Und Sie in jedem Fragment möchte nicht implementieren app:layout_behavior="@string/appbar_scrolling_view_behavior"können , müssen Sie außer Kraft setzen onAttachund onDetachMethoden , die das Verhalten Ihres ändern wird FrameLayout:

CoordinatorLayout.Behavior behavior;

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    if(behavior != null)
        return;

    FrameLayout layout =(FrameLayout) getActivity().findViewById(R.id.dashboard_content);
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) layout.getLayoutParams();

    behavior = params.getBehavior();
    params.setBehavior(null);

}

@Override
public void onDetach() {
    super.onDetach();
    if(behavior == null)
        return;

    FrameLayout layout =(FrameLayout) getActivity().findViewById(R.id.dashboard_content);
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) layout.getLayoutParams();

    params.setBehavior(behavior);

    layout.setLayoutParams(params);

    behavior = null;
}

Danach wird CoordinatorLayout die App-Leiste usw. nicht mehr reduzieren und Fragment-Layouts in voller Höhe zulassen.


Netter, muss das versuchen und sehen, ob es die Dinge vereinfacht. Vielen Dank.
mobilepotato7

Wenn Sie etwas Einfacheres finden - lassen Sie es mich wissen. Ich denke, es ist möglich, das Verhalten des Koordinators jederzeit während des Lebenszyklus von Fragmenten zu ändern (z. B. haben Sie normalerweise einen Recycler mit einigen Dingen, aber in seltenen Fällen ist er möglicherweise leer und Sie werden wissen, dass dies erst nach Loader onLoadFinishedmöglich ist Ich möchte ein zentriertes Bild anzeigen, das darauf hinweist, dass hier nichts ist (genau wie in der Posteingangs-App), aber das habe ich noch nicht versucht. Vielleicht später heute.
Клаус Шварц

Ok, das funktioniert ziemlich gut. Ich habe einen Helfer erstellt, der sich um das Aktivieren / Deaktivieren des Koordinators kümmert, also rufe ich einfach enableCoordinator(Activity activity)/ disableCoordinator(Activity activity)von Fragmenten an.
17лаус Шварц

Wo ist dein Helfer, @ КлаусШварц? Wann nennst du es
Santhyago

1
@ Santhyago im Fragment
30лаус Шварц

8

Hier ist meine Lösung

<!-- Put your fragment inside a Framelayout and set the behavior for this FrameLayout -->
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <!-- Your fragment -->
    <include layout="@layout/content_main" />

</FrameLayout>

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|enterAlways"
        app:popupTheme="@style/AppTheme.PopupOverlay" />

</android.support.design.widget.AppBarLayout>


1

Dies ist eine wirklich gute Frage: Sollten Toolbars, die sich wie ein handeln ActionBarmüssen, in einem Activityoder einem aufbewahrt werden ?Fragment ? Nachdem ich verschiedene Fragen und Dokumentationen durchsucht hatte, konnte ich keine Lösung finden, die alle Fälle abdeckt. Es hängt also wirklich von Ihrer Situation ab, welchen Weg Sie gehen müssen.

Fall 1: Die Symbolleiste muss durch ActionBar ersetzt werden

Wenn sich die Symbolleiste wie eine normale Aktionsleiste verhalten muss (oder wenn von Zeit zu Zeit maximal 1 Fragment angezeigt wird), ist es meiner Meinung nach am besten / einfachsten, die traditionelle Symbolleiste Activitiesmit der eigenen Symbolleiste zu verwenden und Ihr Fragment dort abzulegen. Auf diese Weise müssen Sie sich keine Gedanken darüber machen, wann welche Symbolleiste angezeigt werden muss.

Das Ändern der ActionBar (-Verhalten) von Fragmenten ist ebenfalls möglich, aber ich würde es nicht empfehlen, da Sie dadurch gezwungen sind, zu verfolgen, welches Fragment die ActionBar wann geändert hat. Ich weiß nicht einmal, ob das Einstellen der ActionBar mehrmals durchgeführt werden kann.

Fall 2: Jedes Fragment sollte eine eigene (Teil der) Symbolleiste haben

Sie können auch verschiedene eigenständige Symbolleisten mit unterschiedlichen Aktionen in verschiedene Fragmente einfügen. Auf diese Weise können Sie verschiedene Fragmente nebeneinander anzeigen - jedes mit seinen eigenen Aktionen in der Symbolleiste - und vorschlagen, dass es sich um eine Symbolleiste handelt (möglicherweise wie die Google Mail-App, obwohl ich mir nicht sicher bin). Dies bedeutet jedoch, dass Sie diese Symbolleisten selbst aufblasen müssten, dies muss jedoch nicht sehr schwierig sein.

Ich hoffe, dies hilft bei der Auswahl.

(Entschuldigung, wenn ich (Sprach-) Fehler gemacht habe)


4
Entschuldigung, aber dies beantwortet die Probleme im Zusammenhang mit der neuen Designbibliothek nicht wirklich. Sicher, die Symbolleiste als Aktionsleiste zu haben, ist das Ziel, aber es kann schwierig sein, mehrere Koordinatorlayouts für verschiedene Arten von Symbolleisten zu haben. Ich habe festgestellt, dass es möglich ist, die Symbolleiste nach Bedarf zu animieren. Ich muss es noch besser testen, aber es scheint, dass es gute Ergebnisse gibt
mobilepotato7
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.