Nakładanie się widoku przewijania z AppBarLayout


103

Chcę zaimplementować wzorzec „Elastyczna przestrzeń z nakładającą się zawartością” z technik przewijania Material Design , takich jak w tym filmie : Elastyczna przestrzeń z nakładającymi się treściami GIF

Mój układ XML wygląda teraz tak:

<android.support.design.widget.CoordinatorLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <android.support.design.widget.AppBarLayout
      android:layout_width="match_parent"
      android:layout_height="192dp"
      android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <android.support.design.widget.CollapsingToolbarLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

      <android.support.v7.widget.Toolbar
          android:layout_height="?attr/actionBarSize"
          android:layout_width="match_parent"
          app:layout_collapseMode="pin"/>
    </android.support.design.widget.CollapsingToolbarLayout>
  </android.support.design.widget.AppBarLayout>

  <android.support.v4.widget.NestedScrollView
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
      <....>
    </LinearLayout>
  </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

Czy istnieje łatwy sposób na osiągnięcie tego za pomocą Biblioteki projektu? Czy też muszę utworzyć niestandardowy układ CoordinatorLayout.Behavior, aby to zrobić?


Szukam przeciwieństwa, obraz wewnątrz CollapsingToolbarLayout powinien pokazać kilka dps więcej za paskiem narzędzi i poniżej NestedScrollView w innym kolorze!
David,

Używałem FrameLayout, RelativeLayout, ale zawsze fragmenty zachodziły na actionBar. Rozwiązaniem było użycie NestedScrollView jako elementu nadrzędnego dla wszystkich fragmentów. Dzięki!
JCarlosR

Odpowiedzi:


148

W rzeczywistości nakładanie widoku przewijania za pomocą AppBarLayout jest funkcją dołączoną do biblioteki obsługi projektów systemu Android : możesz użyć app:behavior_overlapTopatrybutu w swoim NestedScrollView(lub dowolnym widoku używającym ScrollingViewBehavior ), aby ustawić nakładanie się:

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    app:behavior_overlapTop="64dp">

Należy zauważyć, że app:behavior_overlapTopdziała tylko w przypadku widoków, które mają app:layout_behavior="@string/appbar_scrolling_view_behavior"zachowanie używające atrybutu (a nie widok lub nadrzędną grupę widoków, jak zwykle mają zastosowanie atrybuty), stąd behavior_prefiks.

Lub ustaw go programowo za pomocą setOverlayTop () :

NestedScrollView scrollView = ...
CoordinatorLayout.LayoutParams params = 
    (CoordinatorLayout.LayoutParams) scrollView.getLayoutParams();
AppBarLayout.ScrollingViewBehavior behavior =
    (AppBarLayout.ScrollingViewBehavior) params.getBehavior();
behavior.setOverlayTop(128); // Note: in pixels

1
To prawie działa dla mnie, z wyjątkiem mojego RecyclerView (na którym ustawiłem layout_behaviori behavior_overlapTop) kończy się za jego siostrzanym AppBarLayout. Próbowałem zmienić kolejność w XML, ale nie daje to żadnego efektu. Jakieś pomysły, co może być problemem?
Vicky Chijwani

1
Kiedy wyłączam przewijanie (usuwam atrybuty app: layout_scrollFlags) - behawior_overlapTop nie działa - NestedScrollView przechodzi pod AppBarLayout. Czy wiesz, jak to naprawić?
Pavel Biryukov

@PavelBiryukov co zrobiłeś dla API <21?
Vicky Chijwani

1
Witam, u mnie to nie działa. Otrzymujęerror no resource identifier found for attribute behavior_overlayTop
Jack Lynx

1
@Lynx - dość mylące, behavior_overlapTopale setOverlayTop()- nakładanie się vs nakładanie. Upewnij się, że używasz właściwego!
ianhanniballake

21

Oprócz zaakceptowanej odpowiedzi wywołaj setTitleEnabled (false) na swoim CollapsingToolbarLayout, aby tytuł pozostał na górze, jak w przykładzie.

Lubię to:

CollapsingToolbarLayout.setTitleEnabled(false);

lub dodając go w xml w ten sposób:

app:titleEnabled="false"

W przeciwnym razie tytuł mógłby zniknąć za nakładającymi się treściami, chyba że jest to pożądane zachowanie.


2
Możesz umieścić wystarczająco duży rozwiniętyTitleMarginBottom w CollapsingToolbarLayout, aby uniknąć nakładania się tytułu po rozwinięciu.
WindRider
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.