关联地址
细说 AppbarLayout,如何理解可折叠 Toolbar 的定制
coordinatorLayout使用总结篇,看完这篇完全可以开发5.0的高级特效了
CoordinatorLayout + AppBarLayout + CollapsingToolbarLayout + Toolbar
在布局中经常会看到使用 CoordinatorLayout + AppBarLayout + CollapsingToolbarLayout + Toolbar 实现一些联动布局,那么这些都是什么要怎么用呢,一个一个来看。
导入
AppBarLayout 和 CollapsingToolbarLayout 都是由 Material Design 包提供,项目使用时要先导入包:
implementation 'com.android.support:design:x.x.x'
AndroidX方式:
implementation 'com.google.android.material:material:1.2.1'
CoordinatorLayout
根据官方文档的描述 CoordinatorLayout 可以看做 FrameLayout 来用。主要应用如下:
- 作为顶层布局。
- 作为一个或多个子View间特定交互的容器。
CoordinatorLayout 实现子 View 间的交互通过如下三种方式:
anchorinsetEdgeBehaviors
anchor
CoordinatorLayout 的子 View 可以设置 anchor (view id) 作为锚点,当 anchor 指定的 View 移动时,此 View 也会跟随移动。可作为锚点的必须是 CoordinatorLayout 的子孙 View。
示例如下:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<View
android:id="@+id/move_view"
android:layout_gravity="center"
android:background="@color/blue"
android:layout_width="100dp"
android:layout_height="100dp"/>
<View
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@color/color_90b3b3b3"
app:layout_anchor="@id/move_view"
app:layout_anchorGravity="clip_vertical"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
示例中还用到了 layout_anchorGravity 属性,用于设置相对于锚点的位置。
insetEdge
View A 通过 layout_insetEdge 来设置插入 CoordinatorLayout 的方向,View B 通过设置layout_dodgeInsetEdges 来躲避来自相同方向的 View A,这样就可以避免产生重叠。
示例如下:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<View
android:id="@+id/move_view"
android:layout_gravity="center"
android:background="@color/blue"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_insetEdge="right"/>
<View
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center_vertical"
android:background="@color/color_90b3b3b3"
app:layout_dodgeInsetEdges="right"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
FloatingActionButton和Snackbar就和insetEdge有关。
Behaviors
通过为 CoordinatorLayout 的子 View 指定 Behaviors,可以指定子 View 的交互方式,也可以指定子 View 间彼此的交互方式。
详细 Behaviors 在下面👇介绍
AppBarLayout
AppBarLayout 的本质是一个实现了 CoordinatorLayout.AttachedBehavior 接口的 LinearLayout,可以设置实现一些奇妙的滑动效果。
应用如下:
Appbarlayout一般作为CoordinatorLayout的直接子View使用,否则它与普通的LinearLayout无异。- 可以通过
layout_scrollFlags设置AppBarLayout直接子View的滑动行为。Appbarlayout会响应外部的嵌套滑动事件,然后根据特定的规则去伸缩和滑动内部的子View。 AppbarLayout的子View不仅仅是Toolbar,它们可以是任何的View。
layout_scrollFlags 属性可设置的值如下:
scrollenterAlwaysenterAlwaysCollapsedexitUntilCollapsedsnapsnapMargins
注意:其他的属性都是建立在滑动的基础之上的,所以
scroll值是必需的。app:layout_scrollFlags="scroll|enterAlways"
基本使用如下:
scroll
当前 View 将和滑动事件关联。layout_scrollFlags 属性必须设置 scroll 不然设置其他值也没用
scroll|enterAlways
当滑动组件下滑该 View 也会下滑。
scroll|enterAlways|enterAlwaysCollapsed
需和 enterAlways 一起使用来增强 enterAlways 功能,当滑动组件下滑该 View 将先滑动显示 minHeight 高度,滑动组件继续滑动到最顶端时该 View 才会继续下滑。
scroll|exitUntilCollapsed
当滑动组件上滑时该 View 也会上滑,直到其高度缩小到 minHeight 后不再响应上滑事件。
scroll|snap
滑动超过该 View 一半或者未超过一半时松手会自动滑动上滑和下滑。
scroll|snap|snapMargins
需和 snap 一起使用来增强 snap 功能,当设置 layout_marginBottom、layout_marginTop 时需设置 snapMargins。
滑动监听
AppBarLayout滑动监听器。
appBarLayout.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> {
//垂直方向偏移量
int offset = Math.abs(verticalOffset);
//最大偏移距离
int scrollRange = appBarLayout.getTotalScrollRange();
});
CollapsingToolbarLayout
CollapsingToolbarLayout 是 Toolbar 的封装,实现了一个折叠的 app bar。CollapsingToolbarLayout 应作为 AppBarLayout 的子类使用,使用如下:
注意:
CollapsingToolbarLayout是为了增强Toolbar,所以Toolbar需添加到CollapsingToolbarLayout布局中以上属性才能生效。
自身可用属性:
app:title:设置的title会随着滑动其大小和位置会发生变化。app:contentScrim:当CollapsingToolbarLayout折叠时会使用设置的颜色遮罩布局内的View。app:statusBarScrim:当CollapsingToolbarLayout折叠时会使用设置的颜色遮罩手机的状态栏。app:collapsedTitleTextAppearance:折叠时title的样式里面可以定义字体大小颜色等。app:expandedTitleTextAppearance:展开时title的样式里面可以定义字体大小颜色等。
注意:
statusBarScrim但是仅可在Lollipop版本使用,还需设置android:fitSystemWindows="true"。
子View可用属性
app:layout_collapseMode:子 View 的折叠模式。
none:默认,无任何效果Parallax:视差滚动pin:固定View的位置,不随滑动事件变动位置。app:layout_collapseParallaxMultiplier:速度因子。取值范围 0~1,值越小对滑动约敏感,默认0.5。
以上示例代码如下:
<androidx.coordinatorlayout.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">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/myList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"/>
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="200dp"
android:minHeight="?attr/actionBarSize"
app:title="@string/app_name"
app:contentScrim="@color/black"
app:expandedTitleTextAppearance="@style/expanded_title_text"
app:collapsedTitleTextAppearance="@style/collapsed_title_text"
app:layout_scrollFlags="scroll|snap|enterAlwaysCollapsed|exitUntilCollapsed">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="@mipmap/appbar_naruto"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"
app:layout_collapseMode="parallax" />
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
使用注意
-
CoordinatorLayout继承自viewgroup,但是使用类似于framLayout,有层次结构,后面的布局会覆盖在前面的布局之上,但跟behavior属性也有很大关系的,app:layout_behavior属性只有CoordinatorLayout的直接子布局才能响应,所以不要做徒劳无功的事。 -
如果
Toolbar为CollapsingToolbarLayout子View那么CollapsingToolbarLayout折叠后高度就是Toolbar的高度,相当于CollapsingToolbarLayout设置了minHeight属性。 -
实现固定表头:将表头布局放在
CollapsingToolbarLayout之后,AppBarLayout之内即可。
注意
CoordinatorLayout + recyclerview显示不全
- 临时方案:删除Toolbar。