一、CoordinatorLayout
CoordinatorLayout的主要功能是协调内部各个子控件直接的状态关系,也就是说,可以协调多个View进行互动,比如:移动,动画等。它是通过Behavior。代码连接已经放在了最下面,有需要可以下载
二、Behavior
是作用于CoordinatorLayout的子View的交互行为插件。Google给我们提供了一些Behavior,我们也可以自己定义Behavior,代码在最下面
1. BottomSheetBehavior
它是一个从底部弹出一个布局,例如我们经常用的分享功能
1.1 用法
注:我们设置了一个Behavior,bottom_sheet_behavior,是系统提供好的一个behavior,如果一开始需要隐藏的话,可以设置app:behavior_peekHeight=”0dp”
然后在代码中这样写
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,设置一个监听状态的回调,设置了下滑可以隐藏
示例如下:
注意:系统的BottomSheetDialog是基于BottomSheetBehavior封装的,这里判断了当滑动隐藏了BottomSheetBehavior中的View后,内部设置了BottomSheetBehavior的状态为STATE_HIDDEN,所以我们再次调用dialog.show()的时候Dialog没法再打开状态为STATE_HIDE的Dialog,所以我们需要自己来实现,监听用户滑动关闭后,把BottomSheetBehavior的状态再设置为STATE_COLLAPSED
3.SwipeDissmissBehavior
滑动关闭或者滑动消失,Snackbar就是使用的这个,当滑动Snackbar的时候,Snackbar消失
代码也特别简单,在代码中直接new一个SwipeDissmissBehavior,设置属性,添加到CoordinatorLayout.LayoutParams,直接代码截图
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
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。