Android5.0+(CoordinatorLayout) implements various scrolling effects mentioned in Material Design

Original English: https://guides.codepath.com/android/Handling-Scrolls-with-CoordinatorLayout 

This article is dedicated to explaining the knowledge points related to CoordinatorLayout, which is also the most important and difficult part of the Design Support Library.

Overview

CoordinatorLayout implements various scrolling effects  mentioned in Material Design . Currently the framework provides several ways to work without writing animation code, these effects include:

  • Let the floating action button slide up and down to make room for the Snackbar.

CoordinatorLayout and scrolling

  • Expand or shrink the Toolbar or header to make more room in the main content area.

CoordinatorLayout and scrolling

CoordinatorLayout and scrolling

set up

First make sure you follow the instructions for using the Design Support Library .

Floating Action Button with Snackbar

CoordinatorLayout can be used to create a floating effect with the layout_anchor and layout_gravity properties of the floating action button. For details, please refer to the floating action button guide.

Snackbar在显示的时候,往往出现在屏幕的底部。为了给Snackbar留出空间,浮动操作按钮需要向上移动。

CoordinatorLayout and scrolling

只要使用CoordinatorLayout作为基本布局,将自动产生向上移动的动画。浮动操作按钮有一个 默认的 behavior来检测Snackbar的添加并让按钮在Snackbar之上呈现上移与Snackbar等高的动画。

 <android.support.design.widget.CoordinatorLayout
        android:id="@+id/main_content"
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
 
   <android.support.v7.widget.RecyclerView
         android:id="@+id/rvToDoList"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
   </android.support.v7.widget.RecyclerView>
 
   <android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|right"
        android:layout_margin="16dp"
        android:src="@mipmap/ic_launcher"
        app:layout_anchor="@id/rvToDoList"
        app:layout_anchorGravity="bottom|right|end"/>
 </android.support.design.widget.CoordinatorLayout>


CoordinatorLayout and scrolling

Toolbar的扩展与收缩

首先需要确保你不是使用已经过时的ActionBar。务必遵循 使用ToolBar作为actionbar这篇文章的指南。同样,这里也需要CoordinatorLayout作为主布局容器。

 

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">
 
      <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
 
</android.support.design.widget.CoordinatorLayout>

接下来,我们必须使用一个容器布局:
  AppBarLayout  来让Toolbar响应滚动事件。响应滚动事件
<android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/detail_backdrop_height"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        android:fitsSystemWindows="true">
 
  <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
 
 </android.support.design.widget.AppBarLayout>

然后,我们需要定义AppBarLayout与滚动视图之间的联系。在RecyclerView或者任意支持嵌套滚动的view比如NestedScrollView上添加app:layout_behavior。support library包含了一个特殊的字符串资源@string/appbar_scrolling_view_behavior,它和AppBarLayout.ScrollingViewBehavior相匹配,用来通知AppBarLayout 这个特殊的view何时发生了滚动事件,这个behavior需要设置在触发事件(滚动)的view之上。注意:根据官方的谷歌文档,AppBarLayout目前必须是第一个嵌套在CoordinatorLayout里面的子view。

<android.support.v7.widget.RecyclerView
        android:id="@+id/rvToDoList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

AppBarLayout里面定义的view只要设置了app:layout_scrollFlags属性,就可以在RecyclerView滚动事件发生的时候被触发:当CoordinatorLayout发现RecyclerView中定义了这个属性,它会搜索自己所包含的其他view,看看是否有view与这个behavior相关联。AppBarLayout.ScrollingViewBehavior描述了RecyclerView与AppBarLayout之间的依赖关系。RecyclerView的任意滚动事件都将触发AppBarLayout或者AppBarLayout里面view的改变。

<android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
 
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_scrollFlags="scroll|enterAlways"/>
 
 </android.support.design.widget.AppBarLayout>
enterAlways: 一旦向上滚动这个view就可见。app:layout_scrollFlags属性里面必须至少启用scroll这个flag,这样这个view才会滚动出屏幕,否则它将一直固定在顶部。可以使用的其他flag有:
  • enterAlwaysCollapsed: 顾名思义,这个flag定义的是何时进入(已经消失之后何时再次显示)。假设你定义了一个最小高度(minHeight)同时enterAlways也定义了,那么view将在到达这个最小高度的时候开始显示,并且从这个时候开始慢慢展开,当滚动到顶部的时候展开完。

  • exitUntilCollapsed: 同样顾名思义,这个flag时定义何时退出,当你定义了一个minHeight,这个view将在滚动到达这个最小高度的时候消失。

记住,要把带有scroll flag的view放在前面,这样收回的view才能让正常退出,而固定的view继续留在顶部。

此时,你应该注意到我们的Toolbar能够响应滚动事件了。

CoordinatorLayout and scrolling

回到顶部

制造折叠效果

如果想制造toolbar的折叠效果,我们必须把Toolbar放在CollapsingToolbarLayout中:

<android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginEnd="64dp"
            app:expandedTitleMarginStart="48dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
             
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_scrollFlags="scroll|enterAlways"></android.support.v7.widget.Toolbar>
        </android.support.design.widget.CollapsingToolbarLayout>

CoordinatorLayout and scrolling

现在效果就成了:

通常,我们我们都是设置Toolbar的title,而现在,我们需要把title设置在CollapsingToolBarLayout上,而不是Toolbar。

 

CollapsingToolbarLayout collapsingToolbar =(CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
collapsingToolbar.setTitle("Title");

制造视差效果

回到顶部

CollapsingToolbarLayout还能让我们做出更高级的动画,比如在里面放一个ImageView,然后在它折叠的时候渐渐淡出。同时在用户滚动的时候title的高度也会随着改变。

CoordinatorLayout and scrolling

为了制造出这种效果,我们添加一个定义了app:layout_collapseMode="parallax" 属性的ImageView。

 

  <android.support.design.widget.CollapsingToolbarLayout
          android:id="@+id/collapsing_toolbar"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:fitsSystemWindows="true"
          app:contentScrim="?attr/colorPrimary"
          app:expandedTitleMarginEnd="64dp"
          app:expandedTitleMarginStart="48dp"
          app:layout_scrollFlags="scroll|exitUntilCollapsed">
 
          <android.support.v7.widget.Toolbar
              android:id="@+id/toolbar"
              android:layout_width="match_parent"
              android:layout_height="?attr/actionBarSize"
              app:layout_scrollFlags="scroll|enterAlways"></android.support.v7.widget.Toolbar>
          <ImageView
              android:src="@drawable/cheese_1"
              app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:scaleType="centerCrop"
              app:layout_collapseMode="parallax"
              android:minHeight="100dp"/>
 
      </android.support.design.widget.CollapsingToolbarLayout>


We discussed an example of a custom behavior in CoordinatorLayout and Floating Action Buttons . Note: The translation is http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0718/3197.html   .

Custom Behavior

CoordinatorLayout works by searching for child views that define CoordinatorLayout Behavior  , either by using the app:layout_behavior tag in xml or by annotating the view class in code with the @DefaultBehavior modifier. When scrolling occurs, CoordinatorLayout will try to trigger those child views that declare dependencies.

To define CoordinatorLayout Behavior yourself, you need to implement layoutDependsOn() and onDependentViewChanged() methods. For example, AppBarLayout.Behavior defines these two key methods. This behavior is used to make the AppBarLayout change when scrolling occurs.

public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
    return dependency instanceof AppBarLayout;
}
 
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
    // check the behavior triggered
    android.support.design.widget.CoordinatorLayout.Behavior behavior = ((android.support.design.widget.CoordinatorLayout.LayoutParams) dependency.getLayoutParams()).getBehavior();
    if (behavior instanceof AppBarLayout.Behavior) {
        // do stuff here
    }
}

The best way to understand how to implement these custom behaviors is to study AppBarLayout.Behavior and FloatingActionButtion.Behavior. Although the source code has not been released yet, you can use the decompiler integrated in Android Studio 1.2 to view it.

Reference: Android's Material Design Compatibility Library (Design Support Library) 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326747616&siteId=291194637