Coordinatorlayout的使用

CoodinatorLayout 是Google Material Design 中的一个控件,旨在解决开发中的嵌套滑动与事件分发

简介

CorrdinatorLayout继承关系
CoordinatorLayout 继承自 ViewGroup 并实现 NestedScrollingParent 接口,是一个特殊的FrameLayout ,主要功能是协调内部的各个子控件之间的状态关系(滑动、触摸事件传递),也可以当做FrameLayout使用。

使用CoordinatorLayout需要引入design库

	com.android.support:design:版本号

使用代码示例:

<?xml version="1.0" encoding="utf-8"?>
<!--      实现滚动效果最外层必须要是  CoordinatorLayout   -->
<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"
	android:background="@android:color/background_light"
	android:fitsSystemWindows="true"
	>

<!--      利用AppBarLayout 包裹 Toolbar、CollapsingToolbarLayout 等控价,实现头部特殊的滚动效果    -->
	<android.support.design.widget.AppBarLayout
		android:id="@+id/main.appbar"
		android:layout_width="match_parent"
		android:layout_height="300dp"
		android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
		android:fitsSystemWindows="true"
		>
<!--  CollapsingToolbarLayout 是可折叠的ToolBar 布局,能实现视察特效    --->
		<android.support.design.widget.CollapsingToolbarLayout
			android:id="@+id/main.collapsing"
			android:layout_width="match_parent"
			android:layout_height="match_parent"
			android:fitsSystemWindows="true"
			app:layout_scrollFlags="scroll|exitUntilCollapsed"
			app:contentScrim="?attr/colorPrimary"
			app:expandedTitleMarginStart="48dp"
			app:expandedTitleMarginEnd="64dp"
			app:title="@string/app_name"
			>

			<ImageView
				android:id="@+id/main.backdrop"
				android:layout_width="match_parent"
				android:layout_height="match_parent"
				android:scaleType="centerCrop"
				android:fitsSystemWindows="true"
				android:src="@drawable/material_flat"
				app:layout_collapseMode="parallax"
				tools:ignore="ContentDescription"
				/>

			<android.support.v7.widget.Toolbar
				android:id="@+id/main.toolbar"
				android:layout_width="match_parent"
				android:layout_height="?attr/actionBarSize"
				app:layout_collapseMode="pin"
				app:title="Test"/>
		</android.support.design.widget.CollapsingToolbarLayout>
	</android.support.design.widget.AppBarLayout>

<!-- 必须是实现NestedScrollingChild接口的view   否则不能产生滑动效果
       layout_behavior  实现滚动过程中的特效
 -->
	<android.support.v4.widget.NestedScrollView
		android:layout_width="match_parent"
		android:layout_height="match_parent"
		app:layout_behavior="@string/appbar_scrolling_view_behavior"
		>

		<TextView
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:textSize="20sp"
			android:lineSpacingExtra="8dp"
			android:text="@string/lorem"
			android:padding="@dimen/activity_horizontal_margin"
			/>
	</android.support.v4.widget.NestedScrollView>

	<android.support.design.widget.FloatingActionButton
		android:layout_height="wrap_content"
		android:layout_width="wrap_content"
		android:layout_margin="@dimen/activity_horizontal_margin"
		android:src="@drawable/ic_comment_24dp"
		app:layout_anchor="@id/main.appbar"
		app:layout_anchorGravity="bottom|right|end"
		/>
</android.support.design.widget.CoordinatorLayout>

属性解析

1.layout_scrollFlags:

scroll:孩子视图伴随滚动事件而滚出或滚进屏幕

enterAlways:向下滚动时Scrolling View和Child View之间的滚动优先级,当优先滚动的一方全部滚进屏幕之后,另一方才开始滚动

enterAlwaysCollapsed:enterAlways的附加值,这里涉及到孩子视图的高度和最小高度,向下滚动时,孩子视图会先向下滚动至最小高度值,然后Scrolling View才开始滚动,到达边界时,孩子视图再向下滚动,直至显示完全

exitUtilCollapsed:这里也涉及最小高度,发生向上滚动事件时,孩子视图向上滚动退出直至最小高度,然后Scrolling View开始滚动,也就是,Child View不会完全退出屏幕

snap:简单理解,就是Child View的一个吸附效果,也就是说,Child View不会存在局部显示的情况,滚动Child View的部分高度,当我们松开手指时,Child View 要么向上全部滚出屏幕,要么向下全部滚进屏幕,有点类似ViewPager的左右滑动

2.layout_collapseMode (折叠模式) :

pin:设置为这个模式时,当CollapsingToolbarLayout完全收缩后,Toolbar还可以保留在屏幕上。
parallax:设置为这个模式时,在内容滚动时,CollapsingToolbarLayout中的View(比如ImageView)也可以同时滚动,实现视差滚动效果,通常和layout_collapseParallaxMultiplier(设置视差因子)搭配使用

3.CollapsingToolbarLayout特殊属性:

app:collapsedTitleGravity 折叠标题的对齐方式

app:expandedTitleGravity 展开标题的对齐方式

app:collapsedTitleTextAppearance 折叠标题的颜色和大小

app:expandedTitleTextAppearance 展开标题的颜色和大小

app:contentScrim="?attr/colorPrimaryDark" 收缩后的背景色

app:titleEnabled 是否显示标题

app:toolbarId 指定与之关联的ToolBar,如果未指定则默认使用第一个被发现的ToolBar子View

4.FloatingActionButton 属性

app:backgroundTint - 设置FAB的背景颜色

app:rippleColor - 设置FAB点击时的背景颜色

app:borderWidth - 该属性尤为重要,如果不设置0dp,那么在4.1的sdk上FAB会显示为正方形,而且在5.0以后的sdk没有阴影效果。所以设置为borderWidth=“0dp”

app:elevation - 默认状态下FAB的阴影大小

app:pressedTranslationZ - 点击时候FAB的阴影大小

app:fabSize - 设置FAB的大小,该属性有两个值,分别为normal和mini,对应的FAB大小分别为56dp和40dp

src - 设置FAB的图标,Google建议符合Design设计的该图标大小为24dp

5.使用

app:layout_anchor 设置锚点(view的 id)

app:layout_anchorGravity 当前view与锚点view的位置关系,值有 bottom、center、right、left、top等

在使用时,AppBarLayout与NestedScrollView(或者实现了NestedScrollingChild接口的view)一定要作为CoordinatorLayout的直接子view,否则不会产生滑动特效。AppBarLayout是特殊的LinearLayout,与CollapsingToolbarLayout配合使用时,AppBarLayout是CollapsingToolbarLayout的parent,两者颠倒不会产生嵌套滑动效果。CollapsingToolbarLayout是特殊的FrameLayout,要注意里面view的层级关系。

原理解析

CoordinatorLayout 能实现滚动事件的处理,关键是它实现了NestedScrollingParent,能接受到子view(实现NestedScrollingChild)的滑动事件,然后再把有关滑动的信息传递给子view的behavior进行处理消费,最终实现了嵌套滑动,CoordinatorLayout在整个过程中只是相当于一个分发者,没有做任何关于嵌套滑动的事情。

实现嵌套滑动的关键是四个类(接口):

NestedScrollingChild
NestedScrollingParent
NestedScrollingChildHelper
NestedScrollingParentHelper

所以要实现嵌套滑动效果一般使用NestedScrollView或者RecyclerView等实现NestedScrollingChild接口的view。

Behavior

Behavior实现

官方定义:
A Behavior implements one or more interactions that a user can take on a child view. These interactions may include drags, swipes, flings, or any other gestures.
中文:
一个Behavior实现了一个或多个用户可以采取的交互视图。这些相互作用可能包括拖动,滑动,快速滑动,或任何其他的手势。

Behavior 类似于观察者模式,一个View跟随着另外一个view的变化而变化。在Behavior中,被观察的view也就是事件源是dependency,观察的view被称为child。
谷歌官方实现的Behavior
Behavior

Behavior 关键方法

layoutDependsOn
onDependentViewChanged
onStartNestedScroll
onNestedPreScroll
onNestedScroll
onStopNestedScroll
onNestedScrollAccepted
onNestedPreFling
onLayoutChild

自定义Behavior
public class MyBehavior extends CoordinatorLayout.Behavior<TextView>{
// 泛型是child 的类型,是观察者view

public MyBehavior(){
    super();
}

// 坑。。。 不写构造方法报错
public MyBehavior(Context context, AttributeSet attrs){
    super(context,attrs);
}


/**
 * 此方法将至少被调用一次
 * 返回ture 当dependency view 布局或者发生变化时,才会调用 onDependentViewChanged
 * @param parent
 * @param child
 * @param dependency
 * @return
 */
@Override
public boolean layoutDependsOn(@NonNull CoordinatorLayout parent, @NonNull TextView child, @NonNull View dependency) {
    dependency.getId();
    return dependency instanceof Button;
}

@Override
public boolean onDependentViewChanged(@NonNull CoordinatorLayout parent, @NonNull TextView child, @NonNull View dependency) {
    child.setX(dependency.getX() + 200);
    child.setY(dependency.getY() + 200);
    return true;
}

}

使用Behavior
1.app:layout_behavior布局属性
在布局中设置,值为自定义Behavior类的名字字符串(包含路径),类似在AndroidManifest.xml中定义四大组件的名字一样,有两种写法,包含包名的全路径和以"."开头的省略项目包名的路径。

2.@CoordinatorLayout.DefaultBehavior类注解
在需要使用Behavior的控件源码定义中添加该注解,然后通过反射机制获取。这个方式就解决了我们前面产生的疑惑,系统的AppBarLayout、FloatingActionButton都采用了这种方式,所以无需在布局中重复设置。

3.代码中设置
	CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) tv.getLayoutParams();
    MyBehavior behavior = new MyBehavior();
    params.setBehavior(behavior);

初学时一直对AppbarLayout 使用 Behavior 的方式赶到困惑,AppbarLayout 是怎么使用Behavior 来实现嵌套滚动的?是因为给Recyclerview或者NestedScrollView 的xml 布局中指定了app:layout_behavior="@string/appbar_scrolling_view_behavior",所以AppbarLayout才会随着滚动实现各种滚动效果。但是,自定义Behavior的时候,我们知道了childView和dependency View (观察者与被观察着)的概念,要实现嵌套滚动,需要给childView 的xml 布局上设置 layout_behavior 。所以,AppBarLayout 能实现嵌套滚动,肯定不是因为Recyclerview或者NestedScrollView 在Xml 中指定的layout_behavior,而是通过其他的方法。
通过阅读AppBarLayout的源码,我终于明白了原因,AppBarLayout是通过注解的方式依赖的Behavior,实现嵌套滚动。
AppBarLayout

阅读系统已经实现的Behavior,可以帮助我们更好的理解自定义Behavior的使用方法,让我们通过Behavior 实现更加炫酷的交互。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CoordinatorLayout 是 Android Design Support Library 提供的一个特殊的布局容器,它可以协调其内部的子 View 之间的交互行为,实现各种复杂的交互效果,比如 AppBarLayout 和 FloatingActionButton 的联动效果。 CoordinatorLayout 的主要作用是让子 View 之间可以通过 Behavior 进行交互。Behavior 是指子 View 在 CoordinatorLayout 中的交互行为的定义,可以让子 View 之间实现联动效果,如 FloatingActionButton 随着 Snackbar 的出现和消失而改变位置,子 View 之间的交互行为通过 Behavior 实现。 使用 CoordinatorLayout 需要注意以下几点: 1. CoordinatorLayout 必须作为根布局。 2. 子 View 需要设置 app:layout_behavior 属性,指定其交互行为的 Behavior。 3. 子 View 的交互行为需要在 Behavior 中定义。 下面是一个简单的 CoordinatorLayout 的示例: ``` <androidx.coordinatorlayout.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent"> <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <com.google.android.material.appbar.CollapsingToolbarLayout android:layout_width="match_parent" android:layout_height="200dp" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@drawable/image"/> <androidx.appcompat.widget.Toolbar android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="pin"/> </com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.AppBarLayout> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"/> </androidx.coordinatorlayout.widget.CoordinatorLayout> ``` 在上面的示例中,AppBarLayout 和 CollapsingToolbarLayout 实现了一个可折叠的 Toolbar,RecyclerView 使用了 appbar_scrolling_view_behavior Behavior,实现了和可折叠的 Toolbar 的联动效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值