前言
CoordinatorLayout
遵循 Material 风格,结合 AppbarLayout
, CollapsingToolbarLayout
等可产生各种炫酷的效果,本篇博客就将介绍 CoordinatorLayout
的各种酷炫效果。
一、View 介绍
1、CoordinatorLayout
又名协调者布局,它是 support.design
包中的控件。简单来说,CoordinatorLayout
是用来协调其子 view
并以触摸影响布局的形式产生动画效果的一个 super-powered FrameLayout
,其典型的子 View 包括:FloatingActionButton
,SnackBar
。注意:CoordinatorLayout
是一个顶级父 View
。
2、AppBarLayout
AppBarLayout
是 LinearLayout
的子类,必须在它的子 view
上设置 app:layout_scrollFlags
属性或者是在代码中调用 setScrollFlags()
设置这个属性。
AppBarLayout
的子布局有 5 种滚动标识(上面代码 CollapsingToolbarLayout
中配置的 app:layout_scrollFlags
属性):
scroll
:所有想滚动出屏幕的 view 都需要设置这个 flag, 没有设置这个 flag 的 view 将被固定在屏幕顶部。enterAlways
:这个 flag 让任意向下的滚动都会导致该 view 变为可见,启用快速“返回模式”。enterAlwaysCollapsed
:假设你定义了一个最小高度(minHeight)同时 enterAlways 也定义了,那么 view 将在到达这个最小高度的时候开始显示,并且从这个时候开始慢慢展开,当滚动到顶部的时候展开完。exitUntilCollapsed
:当你定义了一个 minHeight,此布局将在滚动到达这个最小高度的时候折叠。snap
:当一个滚动事件结束,如果视图是部分可见的,那么它将被滚动到收缩或展开。例如,如果视图只有底部 25%显示,它将折叠。相反,如果它的底部 75%可见,那么它将完全展开。
3、CollapsingToolbarLayout
CollapsingToolbarLayout
作用是提供了一个可以折叠的 Toolbar
,它继承自 FrameLayout
,给它设置 layout_scrollFlags
,它可以控制包含在 CollapsingToolbarLayout
中的控件(如:ImageView、Toolbar)在响应 layout_behavior
事件时作出相应的 scrollFlags
滚动事件(移除屏幕或固定在屏幕顶端)。
CollapsingToolbarLayout
可以通过 app:contentScrim
设置折叠时工具栏布局的颜色,通过 app:statusBarScrim
设置折叠时状态栏的颜色。默认 contentScrim
是 colorPrimary
的色值,statusBarScrim
是 colorPrimaryDark
的色值。
CollapsingToolbarLayout
的子布局有 3 种折叠模式(Toolbar
中设置的 app:layout_collapseMode
)
off
:默认属性,布局将正常显示,无折叠行为。pin
:CollapsingToolbarLayout 折叠后,此布局将固定在顶部。parallax
:CollapsingToolbarLayout 折叠时,此布局也会有视差折叠效果。
当 CollapsingToolbarLayout 的子布局设置了 parallax 模式时,我们还可以通过 app:layout_collapseParallaxMultiplier 设置视差滚动因子,值为:0~1。
常用属性:
app:contentScrim
:当 Toolbar 收缩到一定程度时的所展现的主体颜色。即 Toolbar 的颜色。app:title
:当 titleEnable 设置为 true 的时候,在 toolbar 展开的时候,显示大标题,toolbar 收缩时,显示为 toolbar 上面的小标题。app:scrimAnimationDuration
:该属性控制 toolbar 收缩时,颜色变化的动画持续时间。即颜色变为 contentScrim 所指定的颜色进行的动画所需要的时间app:collapsedTitleTextAppearance
:指定 toolbar 收缩时,标题字体的样式。app:collapsedTitleGravity
: 指定 toolbar 收缩时的标题文字对齐方式。app:expandedTitleTextAppearance
: 指定 toolbar 展开后的标题文字字体。app:expandedTitleGravity
:指定 toolbar 展开时,title 所在的位置。类似的还有 expandedTitleMargin、collapsedTitleGravity 这些属性。app:expandedTitleMargin
: 指定展开后的标题四周间距。
4、NestedScrollView
在新版的 support-v4
兼容包里面有一个 NestedScrollView
控件,这个控件其实和普通的 ScrollView
并没有多大的区别,这个控件其实是 Meterial Design
中设计的一个控件,目的是跟 MD 中的其他控件兼容。应该说在 MD 中,RecyclerView
代替了 ListView
,而 NestedScrollView
代替了 ScrollView
,他们两个都可以用来跟 ToolBar
交互,实现上拉下滑中 ToolBar
的变化。在 NestedScrollView
的名字中其实就可以看出他的作用了,Nested
是嵌套的意思,而 ToolBar
基本需要嵌套使用。
5、FloatingActionButton
FloatingActionButton
就是一个漂亮的按钮,其本质是一个 ImageVeiw
。有一点要注意,Meterial Design
引入了 Z 轴的概念,就是所有的 view
都有了高度,他们一层一层贴在手机屏幕上,而 FloatingActionButton
的 Z 轴高度最高,它贴在所有 view
的最上面,没有 view
能覆盖它。
6、Behavior
Behavior
只有是 CoordinatorLayout
的直接子 View
才有意义。只要将 Behavior
绑定到 CoordinatorLayout
的直接子元素上,就能对触摸事件(touch events)、window insets、measurement、layout 以及嵌套滚动(nested scrolling)等动作进行拦截。Design Library
的大多功能都是借助 Behavior
的大量运用来实现的。当然,Behavior
无法独立完成工作,必须与实际调用的 CoordinatorLayout
子视图相绑定。具体有三种方式:通过代码绑定、在 XML 中绑定或者通过注释实现自动绑定。
二、应用实战
1、CoordinatorLayout + FloatingActionButton 使用
市面上众多 APP 首页都会使用 CoordinatorLayout
结合 FloatingActionButton
的效果,当列表垂直方向滑动时,FloatingActionButton
随之显示与隐藏。
- 布局文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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"
android:fitsSystemWindows="true"
android:background="@color/white">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="?attr/actionBarSize"
android:clipChildren="false"
android:clipToPadding="false"/>
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
app:titleTextColor="@color/white"
tools:ignore="MissingConstraints" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:onClick="fabClick"
app:layout_behavior=".coordinatorLayout.behavior.FabBehavior"
app:rippleColor="@color/colorPrimaryDark"
app:backgroundTint="@color/colorPrimary"
android:id="@+id/fab"
android:clickable="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="20dp"
app:fabSize="auto