一、CoordinatorLayout

CoordinatorLayout的主要功能是协调内部各个子控件直接的状态关系,也就是说,可以协调多个View进行互动,比如:移动,动画等。它是通过Behavior。代码连接已经放在了最下面,有需要可以下载

二、Behavior

是作用于CoordinatorLayout的子View的交互行为插件。Google给我们提供了一些Behavior,我们也可以自己定义Behavior,代码在最下面

1. BottomSheetBehavior

它是一个从底部弹出一个布局,例如我们经常用的分享功能

1.1 用法

 
image

注:我们设置了一个Behavior,bottom_sheet_behavior,是系统提供好的一个behavior,如果一开始需要隐藏的话,可以设置app:behavior_peekHeight=”0dp”

然后在代码中这样写

 
image

BottomSheetBehavior有5种状态

(1)STATE_EXPANDED展开状态,显示完整布局。

(2)STATE_COLLAPSED折叠状态,显示peekHeigth 的高度,如果peekHeight为0,则全部隐藏,与STATE_HIDDEN效果一样。

(3)STATE_DRAGGING拖拽时的状态

(4)STATE_HIDDEN隐藏时的状态

(5)STATE_SETTLING释放时的状态

2. BottomSheetDialog

它是一个Dialog,从底部弹出一个Dialog,比如淘宝商品详情页的立即购买,它是对BottomSheetBehavior的一个封装,是获取一个Behavior,设置一个监听状态的回调,设置了下滑可以隐藏

示例如下:

 
image

注意:系统的BottomSheetDialog是基于BottomSheetBehavior封装的,这里判断了当滑动隐藏了BottomSheetBehavior中的View后,内部设置了BottomSheetBehavior的状态为STATE_HIDDEN,所以我们再次调用dialog.show()的时候Dialog没法再打开状态为STATE_HIDE的Dialog,所以我们需要自己来实现,监听用户滑动关闭后,把BottomSheetBehavior的状态再设置为STATE_COLLAPSED

 
image

3.SwipeDissmissBehavior

滑动关闭或者滑动消失,Snackbar就是使用的这个,当滑动Snackbar的时候,Snackbar消失

代码也特别简单,在代码中直接new一个SwipeDissmissBehavior,设置属性,添加到CoordinatorLayout.LayoutParams,直接代码截图

 
image

4. 自定义Behavior

Google为我们提供了一些场景使用的Behavior,但是有时候,要实现多个View之间的交互,我们可以使用自定义Behavior

4.1 第一种是通过监听一个View的状态,如果位置,大小的变化,来改变其它View的行为,这种只需要重写两个方法就可以了,分别是layoutDependsOn和onDependentViewChanged,layoutDependsOn方法判断是指定依赖的View时,返回true,然后在onDependentViewChange里,被依赖的View做需要的行为动作

4.2 第二种就是重写onStartNestedScroll、onNestedPreScroll等

具体方法:


/**** 

* 表示是否给应用了Behavior 的View 指定一个依赖的布局,通常,当依赖的View 布局发生变化时

* 不管被被依赖View 的顺序怎样,被依赖的View也会重新布局

* @param parent

* @param child 绑定behavior 的View

* @param dependency 依赖的view

* @return 如果child 是依赖的指定的View 返回true,否则返回false

*/

案例:仿知乎首页滑动隐藏/显示

它是CoordinatorLayout的子View之间的交互,实现子View随着RecyclerView的滚动显示或者隐藏,只需要滑动一段距离,来显示隐藏,实现onNestedScroll(),在里面判断View需要移动的位置,然后在进行动画移动


//向上的时候是出来,向下是隐藏

if(dyConsumed>0){//往上滑动,是隐藏,需要加一个标志位

    if(!isOut){//不是往下走,需要往下走

        CoordinatorLayout.LayoutParams params=(CoordinatorLayout.LayoutParams)child.getLayoutParams();

child.animate().translationY(params.bottomMargin+child.getMeasuredHeight()).setDuration(300).start();

//处理底部位移动画

        mBottomTabView.animate().translationY(mBottomTabView.getMeasuredHeight()).setDuration(300).start();

isOut=true;

}

}else {//往下滑动

    if(isOut){

child.animate().translationY(0).setDuration(300).start();

//处理底部位移动画

        mBottomTabView.animate().translationY(0).setDuration(300);

isOut=false;

}

}

注:1.自定义Behavior构造方法一定要重载!!!不然会报错

   2.底部移动和隐藏需要先在onLayoutChild()里面获取底部控件id,然后再在onNestedScroll()写移动动画


Override

public boolean onLayoutChild(CoordinatorLayout parent, FloatingActionButton child,int layoutDirection) {

mBottomTabView = parent.findViewById(R.id.bottom_tab_layout);

return super.onLayoutChild(parent, child, layoutDirection);

}

具体代码连接:https://github.com/sisirukou/Behavior.git

 

作者:思思入扣
链接:https://www.jianshu.com/p/317b58cb0eae
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。