Układ koordynatora z paskiem narzędzi we fragmentach lub działaniach


95

Dzięki nowej bibliotece projektów dostępnych jest kilka nowych układów, które bardzo zmieniają sposób zachowania paska narzędzi, jeśli programista sobie tego życzy. Ponieważ różne fragmenty mają różne zachowania i cele, na przykład fragment galerii ze zwijanym paskiem narzędzi pokazującym ważne zdjęcie lub fragment bez widoku przewijania, który po prostu nie potrzebuje appbarlayout do ukrycia paska narzędzi, posiadanie jednego paska narzędzi w działaniu może okazują się trudne.

Czy w związku z tym powinienem przenieść pasek narzędzi do każdego fragmentu? Jeśli tak, to za każdym razem, gdy pokazuję fragment, muszę ustawić supportActionBar, a także mieć odniesienie do aktywności we fragmencie, co unieważnia niezależny charakter fragmentów. Jeśli zostawię pasek narzędzi w samym działaniu, muszę mieć zdefiniowane wiele układów dla każdego typu zachowania w każdym fragmencie. Jakie byłoby najlepsze podejście?


1
Cześć, czy znalazłeś rozwiązanie?
SERG,

2
dla mojego obecnego projektu zdecydowałem się pozostać przy pasku narzędzi w ćwiczeniu i wykonywać odpowiednie animacje, gdy jest to wymagane. Ale jest trochę zagmatwany. Próbowałem użyć paska narzędzi w każdym fragmencie i działa dobrze, ale animowanie paska narzędzi między przejściami fragmentów jest trudniejsze i nawet nie wiem, czy jest to możliwe, ponieważ nie mam dużego doświadczenia z animacjami przejść między fragmentami.
mobilepotato7

jakieś aktualizacje lub lepsze rozwiązania teraz?
Sagar Nayak

Odpowiedzi:


56

Jak dla mnie brzmi to zbyt dziwnie, aby mieć pasek aplikacji i pasek narzędzi w każdym fragmencie. Więc zdecydowałem się mieć pojedynczy pasek aplikacji z paskiem narzędzi w aktywności.

Aby rozwiązać ten problem za pomocą CoordinatorLayout, będziesz musiał ustawić inne zachowanie swojego FrameLayout(lub dowolnego innego układu), który powinien przechowywać fragmenty z każdego fragmentu, który chcesz przesłonić domyślne zachowanie.

Załóżmy, że domyślne zachowanie to app:layout_behavior="@string/appbar_scrolling_view_behavior"

Wtedy w twoim fragment_activity_layout.xml możesz mieć coś takiego:

<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>

I w każdym fragmencie, którego nie chcesz implementować app:layout_behavior="@string/appbar_scrolling_view_behavior", będziesz musiał nadpisać onAttachi onDetachmetody, które zmienią zachowanie twojego 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;
}

Po tym CoordinatorLayout nie zwinie paska aplikacji itp. I pozwoli na układy fragmentów na pełną wysokość.


Niezły, będzie musiał spróbować tego i zobaczyć, czy to upraszcza sprawę. Dzięki.
mobilepotato7

Jeśli znajdziesz coś prostszego - daj mi znać. Myślę, że można zmienić zachowanie koordynatora w dowolnym momencie podczas cyklu życia fragmentów (np. Normalnie masz recykler z jakimiś rzeczami, ale w rzadkich przypadkach może być pusty i będziesz wiedział, że dopiero po Loaderze onLoadFinishedmożliwe, że lubię wyświetlać wyśrodkowany obraz z informacją, że nic tu nie ma, tak jak w aplikacji Inbox), ale jeszcze tego nie próbowałem. Może później dzisiaj.
Клаус Шварц

Ok, to działa całkiem nieźle. Utworzyłem pomocnika, który zajmie się włączaniem / wyłączaniem koordynatora w razie potrzeby, więc po prostu dzwonię enableCoordinator(Activity activity)/ disableCoordinator(Activity activity)z fragmentów.
Клаус Шварц

Gdzie jest Twój pomocnik @ КлаусШварц? Kiedy to nazywasz?
santhyago

1
@santhyago In the Fragment
Клаус Шварц

8

Oto moje rozwiązanie

<!-- 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

To naprawdę dobre pytanie: czy Toolbarto powinno zachowywać się jak ActionBartrzymany w a Activityczy a Fragment? Po przeszukaniu różnych pytań i dokumentacji nie mogłem znaleźć rozwiązania obejmującego wszystkie przypadki. Dlatego tak naprawdę zależy to od Twojej sytuacji.

Przypadek 1: Pasek narzędzi musi być zamiennikiem ActionBar

Jeśli pasek narzędzi ma zachowywać się jak normalny pasek akcji (lub jeśli od czasu do czasu wyświetlany jest maksymalnie 1 fragment), myślę, że najlepszym / najprostszym sposobem jest użycie tradycyjnego Activitiesz własnym paskiem narzędzi i umieszczenie tam swojego fragmentu. W ten sposób nie musisz się martwić, kiedy pasek narzędzi ma zostać wyświetlony.

Zmiana ActionBar (-behaviour) z Fragments jest również możliwa, ale nie polecam tego, ponieważ zmusza cię to do śledzenia, który Fragment zmienił ActionBar i kiedy. Nie wiem nawet, czy ustawienie ActionBar można wykonać wiele razy.

Przypadek 2: Każdy fragment powinien mieć własny (część) paska narzędzi

Możesz także umieścić różne samodzielne paski narzędzi w różnych fragmentach, z ich własnymi akcjami. W ten sposób możesz wyświetlać różne fragmenty obok siebie - każdy z własnymi akcjami na swoim pasku narzędzi - i zasugerować, że jest to 1 pasek narzędzi (może podobnie jak aplikacja Gmail, chociaż nie jestem pewien). Oznacza to jednak, że musiałbyś sam nadmuchać te paski narzędzi, ale nie może to być zbyt trudne.

Mam nadzieję, że pomoże to w dokonaniu wyboru.

(Przepraszam, jeśli popełniłem jakieś (językowe) błędy)


4
przepraszam, ale to tak naprawdę nie rozwiązuje problemów związanych z nową biblioteką projektów. Oczywiście, celem jest posiadanie paska narzędzi jako paska działań, ale posiadanie wielu układów koordynatorów dla różnych typów pasków narzędzi może być trudne. Odkryłem, że w razie potrzeby można animować pasek narzędzi. Nadal muszę to lepiej przetestować, ale wygląda na to, że są dobre wyniki
mobilepotato7
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.