世界观天下!Android 5.0中CoordinatorLayout的使用技巧

时间:2022-10-01 19:35:34       来源:互联网

CoordinatorLayout 实现了多种Material Design中提到的滚动效果。目前这个框架提供了几种不用写动画代码就能工作的方法,这些效果包括:


【资料图】

*让浮动操作按钮上下滑动,为Snackbar留出空间。
*扩展或者缩小Toolbar或者头部,让主内容区域有更多的空间。
*控制哪个view应该扩展还是收缩,以及其显示大小比例,包括视差滚动效果动画。

浮动操作按钮与Snackbar

CoordinatorLayout可以用来配合浮动操作按钮的 layout_anchor 和 layout_gravity属性创造出浮动效果。
当Snackbar在显示的时候,往往出现在屏幕的底部。为了给Snackbar留出空间,浮动操作按钮需要向上移动。

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

<android.support.design.widget.CoordinatorLayout 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:background="#9d9d9d"  android:layout_height="match_parent"/> <android.support.design.widget.FloatingActionButton  android:id="@+id/fab"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_gravity="end|bottom"  android:layout_margin="16dp"  app:layout_anchor="@id/rvToDoList"  app:layout_anchorGravity="bottom|right|end"/> <!--app:layout_anchor:意思是FAB浮动按钮显示在哪个布局区域。且设置当前锚点的位置 app:layout_anchorGravity:意思FAB浮动按钮在这个布局区域的具体位置。两个属性共同作用才是的FAB 浮动按钮也能折叠消失,出现。 --></android.support.design.widget.CoordinatorLayout>
protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {   @Override   public void onClick(View v) {    Snackbar.make(v, "test", Snackbar.LENGTH_LONG)      .setAction("Cancel", new View.OnClickListener() {       @Override       public void onClick(View v) {        //这里的单击事件代表点击消除Action后的响应事件        Toast.makeText(MainActivity.this,"asdasd",Toast.LENGTH_SHORT).show();       }      }).show();   }  }); }

Toolbar的扩展与收缩

首先需要确保你不是使用已经过时的ActionBar,使用ToolBar作为actionbar。同样,这里也需要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>

app:layout_scrollFlags是一个非常重要的属性,它里边的取值主要有五种,下面我分别来解释:

1.scroll 表示CollapsingToolbarLayout可以滚动(不设置的话头部的ImageView将不能折叠),如果想将所有的View能滚动出屏幕,必须设置个flag,若没有设置flag的View,则会被固定在屏幕顶部
2.enterAlways 表示底部的滚动控件只要向下滚动,头部就显示出来,设置这个flag时,向下的滚动都会导致该view变为可见。当ScrollView往下滚动时,该View会直接往下滚动。而不用考虑ScrollView是否在滚动。
3.enterAlwaysCollapsed 表示当底部滚动控件滚动见顶时,头部显示出来,在ScrollView往上滑动时,首先是View把滑动事件“夺走”,由View去执行滑动,直到滑动最小高度后,把这个滑动事件“还”回去,让ScrollView内部去上滑。
4.exitUntilCollapsed 表示头部折叠到最小高度时(Toolbar的高度),就不再折叠,是enterAlways的附加选项,一般跟enterAlways一起使用,它是指,View在往下“出现”的时候,首先是enterAlways效果,当View的高度达到最小高度时,View就暂时不去往下滚动,直到ScrollView滑动到顶部不再滑动时,View再继续往下滑动,直到滑到View的顶部结束。
5.snap 表示在滑动过程中如果停止滑动,则头部会就近折叠(要么恢复原状,要么折叠成一个Toolbar)
记住,要把带有scroll flag的view放在前面,这样收回的view才能让正常退出,而固定的view继续留在顶部。

制造折叠效果

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

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/main_content" tools:context="wxt.coordinatorlayout.AppBarLayout"> <android.support.design.widget.AppBarLayout  android:id="@+id/appbar"  android:layout_width="match_parent"  android:layout_height="wrap_content"  >  <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> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.NestedScrollView  android:layout_width="match_parent"  android:layout_height="wrap_content"  app:layout_behavior="@string/appbar_scrolling_view_behavior">  <TextView   android:layout_width="match_parent"   android:layout_height="wrap_content"   android:text="aaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\naaaa\n" /> </android.support.v4.widget.NestedScrollView>

现在效果就成了:

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

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

制造视差效果CollapsingToolbarLayout

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

CollapsingToolbarLayout作用是提供了一个可以折叠的Toolbar,它继承至FrameLayout,给它设置layout_scrollFlags,它可以控制包含在CollapsingToolbarLayout中的控件(如:ImageView、Toolbar)在响应layout_behavior事件时作出相应的scrollFlags滚动事件(移除屏幕或固定在屏幕顶端)。

使用CollapsingToolbarLayout:

<android.support.design.widget.AppBarLayout  android:layout_width="match_parent"  android:layout_height="256dp"  android:fitsSystemWindows="true">  <android.support.design.widget.CollapsingToolbarLayout   android:id="@+id/collapsing_toolbar_layout"   android:layout_width="match_parent"   android:layout_height="match_parent"   app:contentScrim="#30469b"   app:expandedTitleMarginStart="48dp"   app:layout_scrollFlags="scroll|exitUntilCollapsed">   <ImageView    android:layout_width="match_parent"    android:layout_height="match_parent"    android:scaleType="centerCrop"    android:src="@mipmap/bg"    app:layout_collapseMode="parallax"    app:layout_collapseParallaxMultiplier="0.7" />   <android.support.v7.widget.Toolbar    android:id="@+id/toolbar"    android:layout_width="match_parent"    android:layout_height="?attr/actionBarSize"    app:layout_collapseMode="pin" />  </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout>

我们在CollapsingToolbarLayout中设置了一个ImageView和一个Toolbar。并把这个CollapsingToolbarLayout放到AppBarLayout中作为一个整体。

1、在CollapsingToolbarLayout中:

其中还设置了一些属性,简要说明一下:

contentScrim - 设置当完全CollapsingToolbarLayout折叠(收缩)后的背景颜色。

expandedTitleMarginStart - 设置扩张时候(还没有收缩时)title向左填充的距离。

2、在ImageView控件中:

我们设置了:

layout_collapseMode (折叠模式) - 有两个值:

pin - 设置为这个模式时,当CollapsingToolbarLayout完全收缩后,Toolbar还可以保留在屏幕上。

parallax - 设置为这个模式时,在内容滚动时,CollapsingToolbarLayout中的View(比如ImageView)也可以同时滚动,实现视差滚动效果,通常和layout_collapseParallaxMultiplier(设置视差因子)搭配使用。

layout_collapseParallaxMultiplier(视差因子) - 设置视差滚动因子,值为:0~1。

3、在Toolbar控件中:

我们设置了layout_collapseMode(折叠模式):为pin。

综上分析:当设置了layout_behavior的控件响应起了CollapsingToolbarLayout中的layout_scrollFlags事件时,ImageView会有视差效果的向上滚动移除屏幕,当开始折叠时CollapsingToolbarLayout的背景色(也就是Toolbar的背景色)就会变为我们设置好的背景色,Toolbar也一直会固定在最顶端。

【注】:使用CollapsingToolbarLayout时必须把title设置到CollapsingToolbarLayout上,设置到Toolbar上不会显示。即:

mCollapsingToolbarLayout.setTitle(” “);

该变title的字体颜色:

扩张时候的title颜色:mCollapsingToolbarLayout.setExpandedTitleColor();

收缩后在Toolbar上显示时的title的颜色:mCollapsingToolbarLayout.setCollapsedTitleTextColor();

这个颜色的过度变化其实CollapsingToolbarLayout已经帮我们做好,它会自动的过度,比如我们把收缩后的title颜色设为绿色。

CoordinatorLayout与CollapsingToolbarLayout:
CollapsingToolbarLayout的作用提供了一个可以折叠的Toolbar,对Toolbar进行再次包装的ViewGroup,继承FragmentLayout,它需要放在AppBarLayout布局里面,并且作为AppBarLayout的直接子View。CollapsingToolbarLayout主要包括几个功能:
①:折叠Title(Collapsing title):当布局内容全部显示出来时,title是最大的,但是随着View逐步移出屏幕顶部,title变得越来越小。你可以通过CollapsingToolbarLayout调用setTitle函数来设置title。

②:内容纱布(Content scrim):根据滚动的位置是否到达一个阀值,来决定是否对View“盖上纱布”。可以通过setContentScrim(Drawable)来设置纱布的图片.ToolBar被折叠到顶部固定时候的背景,你可以调用setContentScrim(Drawable)方法改变背景或者 在属性中使用 app:contentScrim=”?attr/colorPrimary”来改变背景。

③:状态栏纱布(Status bar scrim):根据滚动位置是否到达一个阀值决定是否对状态栏“盖上纱布”,你可以通过setStatusBarScrim(Drawable)来设置纱布图片,调用方法setStatusBarScrim(,l)设置状态栏的背景,但是只能在LOLLIPOP设备上面有作用。这个只能在Android5.0以上系统有效果。

④ollapseMode :子视图的折叠模式,在子视图设置,有两种,想要明确的看到效果可以给Toolbar设置一个背景颜色
(1)“pin”:固定模式,在折叠的时候最后固定在顶端;
(2)“parallax”:视差模式,在折叠的时候会有个视差折叠的效果。我们可以在布局中使用属性app:layout_collapseMode=”parallax”来改变:

(1):将子View位置固定(Pinned position children):子View可以选择是否在全局空间上固定位置,这对于Toolbar来说非常有用,因为当布局在移动时,可以将Toolbar固定位置而不受移动的影响。 将app:layout_collapseMode设为pin。

(2):视差滚动子View(Parallax scrolling children):子View可以选择在当前的布局当时是否以“视差”的方式来跟随滚动。(:其实就是让这个View的滚动的速度比其他正常滚动的View速度稍微慢一点)。将布局参数app:layout_collapseMode设为parallax,值的范围[0.0,1.0],值越大视察越大。

app:layout_collapseMode=”parallax”表示ImageView的折叠和CollapsingToolbarLayout的折叠不同步,那么这个不同步到底是怎样一个不同步法呢?还有另外一个参数来设置不同步的参数,如下:
app:layout_collapseParallaxMultiplier=”0.5”表示视觉乘数,该数值的取值为0~1,数值越大,视觉差越大(如果这里的值为0,则在头部折叠的过程中,ImageView的顶部在慢慢隐藏,底部不动,如果这里的值为1,ImageView的顶部不懂,底部慢慢隐藏,如果这里的取值为0~1之间,则在折叠的过程中,ImageView的顶部和底部都会隐藏,但是头部和底部隐藏的快慢是不一样的,具体速度和视觉乘数有关)
app:layout_collapseMode这个属性还有一个取值,是pin,该属性表示当折叠完成时将该控件放在页面的头部.

最终的代码:

<android.support.design.widget.CoordinatorLayout  xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <android.support.design.widget.AppBarLayout  android:layout_width="match_parent"  android:layout_height="256dp"  android:fitsSystemWindows="true">  <android.support.design.widget.CollapsingToolbarLayout   android:id="@+id/collapsing_toolbar_layout"   android:layout_width="match_parent"   android:layout_height="match_parent"   app:contentScrim="#30469b"   app:expandedTitleMarginStart="48dp"   app:expandedTitleTextAppearance="@style/TextAppearance.AppCompat.Title"   app:collapsedTitleTextAppearance="@style/TextAppearance.AppCompat.Title"   app:layout_scrollFlags="scroll|exitUntilCollapsed">   <ImageView    android:layout_width="match_parent"    android:layout_height="match_parent"    android:scaleType="centerCrop"    android:src="@mipmap/bg"    app:layout_collapseMode="parallax"    app:layout_collapseParallaxMultiplier="0.7" />   <android.support.v7.widget.Toolbar    android:id="@+id/toolbar"    android:layout_width="match_parent"    android:layout_height="?attr/actionBarSize"    app:layout_collapseMode="pin" />  </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <LinearLayout  android:layout_width="match_parent"  android:layout_height="match_parent"  android:orientation="vertical"  app:layout_behavior="@string/appbar_scrolling_view_behavior">  <android.support.v7.widget.RecyclerView   android:id="@+id/recyclerView"   android:layout_width="match_parent"   android:layout_height="match_parent"   android:scrollbars="none" /> </LinearLayout></android.support.design.widget.CoordinatorLayout>

Java代码

Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);  setSupportActionBar(mToolbar);  getSupportActionBar().setDisplayHomeAsUpEnabled(true);  mToolbar.setNavigationOnClickListener(new View.OnClickListener() {   @Override   public void onClick(View v) {    onBackPressed();   }  });  //使用CollapsingToolbarLayout必须把title设置到CollapsingToolbarLayout上,设置到Toolbar上则不会显示  CollapsingToolbarLayout mCollapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar_layout);  mCollapsingToolbarLayout.setTitle("CollapsingToolbarLayout");  //通过CollapsingToolbarLayout修改字体颜色  mCollapsingToolbarLayout.setExpandedTitleColor(Color.WHITE);//设置还没收缩时状态下字体颜色  mCollapsingToolbarLayout.setCollapsedTitleTextColor(Color.GREEN);//设置收缩后Toolbar上字体的颜色

以上就是本文的全部内容,希望对大家的学习有所帮助,。

关键词: Android CoordinatorLayout