Перекрытие прокрутки с помощью AppBarLayout

103

Я хочу реализовать шаблон «Гибкое пространство с перекрывающимся содержимым» из методов прокрутки Material design , например, в этом видео : Гибкое пространство с перекрывающимся содержимым GIF

Мой XML-макет сейчас выглядит так:

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

Есть ли простой способ сделать это с помощью библиотеки дизайна? Или мне нужно создать собственный CoordinatorLayout.Behavior для этого?

ianhanniballake
источник
Я ищу противоположное, изображение внутри CollapsingToolbarLayout должно показать еще несколько дпс после панели инструментов и под NestedScrollView другим цветом!
Дэвид
Я использовал FrameLayout, RelativeLayout, но всегда фрагменты перекрывались actionBar. Решением было использование NestedScrollView в качестве родителя для всех фрагментов. Спасибо!
JCarlosR

Ответы:

148

Фактически, наложение прокручиваемого представления с AppBarLayout - это включенная функция библиотеки поддержки дизайна Android : вы можете использовать app:behavior_overlapTopатрибут в своем NestedScrollView(или любом представлении, использующем ScrollingViewBehavior ), чтобы установить величину перекрытия:

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

Обратите внимание, что app:behavior_overlapTopработает только с представлениями, которые имеют app:layout_behavior="@string/appbar_scrolling_view_behavior"атрибут, поскольку именно поведение использует атрибут (а не представление или родительская группа представлений, как атрибуты обычно применяются), отсюда и behavior_префикс.

Или установите его программно через setOverlayTop () :

NestedScrollView scrollView = ...
CoordinatorLayout.LayoutParams params = 
    (CoordinatorLayout.LayoutParams) scrollView.getLayoutParams();
AppBarLayout.ScrollingViewBehavior behavior =
    (AppBarLayout.ScrollingViewBehavior) params.getBehavior();
behavior.setOverlayTop(128); // Note: in pixels
ianhanniballake
источник
1
У меня это почти работает, за исключением того, что мой RecyclerView (на котором я установил layout_behaviorи behavior_overlapTop) оказывается позади своего брата AppBarLayout. Я пробовал изменить порядок в XML, но, похоже, это не помогло. Есть идеи, в чем может быть проблема?
Vicky Chijwani
1
Когда я отключаю прокрутку (удаляя атрибуты app: layout_scrollFlags) - behavior_overlapTop не работает - NestedScrollView переходит в AppBarLayout. Вы знаете, как это исправить?
Павел Бирюков
@PavelBiryukov что вы сделали для API <21?
Вики Чижвани 02
1
Привет, у меня не работает. Я получаюerror no resource identifier found for attribute behavior_overlayTop
Jack Lynx
1
@Lynx - как ни странно, behavior_overlapTopно setOverlayTop()- перекрытие против наложения. Убедитесь, что вы используете правильный!
ianhanniballake
21

В дополнение к принятому ответу вызовите setTitleEnabled (false) на CollapsingToolbarLayout, чтобы заголовок оставался фиксированным вверху, как в примере.

Как это:

CollapsingToolbarLayout.setTitleEnabled(false);

или добавив его в xml вот так:

app:titleEnabled="false"

В противном случае заголовок может исчезнуть за перекрывающимся контентом, если, конечно, это не то поведение, которое вы хотите.

G.deWit
источник
2
Вы можете поместить достаточно большое значение expandTitleMarginBottom в CollapsingToolbarLayout, чтобы избежать перекрытия заголовка при раскрытии.
WindRider