wake-up-neo.com

Koordinatorlayout mit Symbolleiste in Fragmenten oder Aktivität

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

Soll ich also die Symbolleiste auf jedes Fragment verschieben? In diesem Fall muss ich die supportActionBar jedes Mal einstellen, wenn ich ein Fragment zeige. Außerdem muss ich einen Verweis auf die Aktivität im Fragment haben, wodurch die Unabhängigkeit der Fragmente aufgehoben wird. Wenn ich die Symbolleiste in der Aktivität alleine lasse, müssen für jeden Verhaltenstyp in jedem Fragment mehrere Layouts definiert werden. Was wäre der beste Ansatz?

92
mobilepotato7

Für mich klingt es zu seltsam, in jedem Fragment Appbar und Toolbar zu haben. Daher habe ich mich für eine einzelne App-Leiste mit aktivierter Symbolleiste 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 app:layout_behavior="@string/appbar_scrolling_view_behavior" Ist.

Dann können Sie in Ihrer fragment_activity_layout.xml so etwas haben:

<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 in jedem Fragment, das Sie nicht implementieren möchten app:layout_behavior="@string/appbar_scrolling_view_behavior", Müssen Sie die Methoden onAttach und onDetach überschreiben, die das Verhalten Ihres FrameLayout ändern:

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 einklappen und Fragment-Layouts in voller Höhe zulassen.

52

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>

Dies ist eine wirklich gute Frage: Sollen Toolbars, die sich wie ein ActionBar verhalten müssen, in einem Activity oder einem Fragment aufbewahrt werden? 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 ActionBar verhalten muss (oder wenn von Zeit zu Zeit maximal 1 Fragment angezeigt wird), ist es meiner Meinung nach die beste/einfachste Möglichkeit, das traditionelle Activities mit der eigenen Symbolleiste zu verwenden und das Fragment darin abzulegen Dort. Auf diese Weise müssen Sie sich keine Gedanken machen, wann welche Symbolleiste angezeigt werden muss.

Das Ändern der ActionBar (-Verhalten) aus Fragmenten ist ebenfalls möglich, aber ich würde es nicht empfehlen, da dies Sie dazu zwingt, zu verfolgen, welches Fragment die ActionBar wann geändert hat. Ich weiß nicht einmal, ob die ActionBar mehrmals eingestellt werden kann.

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

Sie können auch verschiedene eigenständige Symbolleisten mit ihren eigenen 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 nicht sicher bin). Dies bedeutet jedoch, dass Sie diese Symbolleisten selbst aufpumpen müssten, aber es muss nicht sehr schwierig sein.

Ich hoffe, das hilft bei der Auswahl.

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

1
Coen B