简单分析一下CoordinatorLayout的Behavior机制以及其中方法的作用

Behavior从哪来

Google 推出 Material Design 后,提供了Support Library ,而Behavior机制是其中 CoordinatorLayout的一种使其子View通过Drag、Fling或Gestures 等方式实现子View的各种交互效果而提供的一种实现方式。

Behavior是什么

见名知意,翻译过来就是行为的意思,对,简单来说就是控制一些子View的交互行为。当然父布局必须使用CoordinateLayotu才行。

Behavior有什么用,有什么好处

系统自带了有个两个,一个是BottomSheetBehavior和ScrollingBehavior,BottomSheetBehavior可以帮助我们实现抽屉式的布局;ScrollingBehavior可以帮我们处理AppbarLayout与带有scrollBehavior属性View的滑动事件,一般我们都会结合CollapsingToolbarLayout实现顶部折叠的滑动效果。有什么好处呢。。可以实现非常好看的交互效果,并且实现方式也必较简单。

Behavior怎么用

使用layout_behavior属性,添加到你的View上,layout_behavior的值是一个继承了Behavior的类。然后系统就会自动解析并将Behavior中定义的效果展示出来了。比如我们常用

```

app:layout_behavior="@string/appbar_scrolling_view_behavior"

```

这个其实我们就是使用SupportLibrary为我们自带的实现滑动效果的Behavior了,我们经常会用其与AppBarLayout实现一些联动效果。

除了系统提供的,如果不能满足我们的需求,我们就需要自定义了,如何自定义呢,我们只需要新建一个类,然后继承CoordinatorLayout.Behavior就可以了,我们可以来看一下其中主要的方法。

我们需要先理解两个概念,一个是childView 一个是dependencyView,我们主要是将childView添加上behavior属性,然后让其与dependencyView产生联动效果(比如在dependencyView高度发生变化的时候,childView有一些动画xiao)。

```

public class BottomScrollBehavior<V extends View> extends CoordinatorLayout.Behavior<V> {

    public BottomScrollBehavior() {
        super();
    }

    public BottomScrollBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, V child, View dependency) {
        return super.layoutDependsOn(parent, child, dependency);
    }

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, V child, View dependency) {
        return super.onDependentViewChanged(parent, child, dependency);
    }

    @Override
    public void onDependentViewRemoved(CoordinatorLayout parent, V child, View dependency) {
        super.onDependentViewRemoved(parent, child, dependency);
    }

    @Override
    public boolean onLayoutChild(CoordinatorLayout parent, V child, int layoutDirection) {
        return super.onLayoutChild(parent, child, layoutDirection);
    }

    @Override
    public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull V child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) {
        return super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes, type);
    }

    @Override
    public void onNestedScrollAccepted(@NonNull CoordinatorLayout coordinatorLayout, @NonNull V child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) {
        super.onNestedScrollAccepted(coordinatorLayout, child, directTargetChild, target, axes, type);
    }

    @Override
    public void onStopNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull V child, @NonNull View target, int type) {
        super.onStopNestedScroll(coordinatorLayout, child, target, type);
    }

    @Override
    public void onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull V child, @NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) {
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type);
    }

    @Override
    public void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull V child, @NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) {
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
    }

    @Override
    public boolean onNestedFling(@NonNull CoordinatorLayout coordinatorLayout, @NonNull V child, @NonNull View target, float velocityX, float velocityY, boolean consumed) {
        return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed);
    }

    @Override
    public boolean onNestedPreFling(@NonNull CoordinatorLayout coordinatorLayout, @NonNull V child, @NonNull View target, float velocityX, float velocityY) {
        return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
    }
}

```

layoutDependsOn方法

parent 父布局,这里父布局必须是CoordinatorLayout
child 使用此Behavior的view
dependency 和此view有依赖关系的view,按照xml布局位置,在这child上方的view的就是dependency,如果上方没有就找最后一个
返回true代表你使用其和此dependency依赖,则dependency的布局有变化的时候就会调用onDependentViewChanged

onDependentViewChanged方法

如果layoutDependsOn返回true才会执行此方法,dependency的布局有变化的时候就会调用onDependentViewChanged
onDependentViewChanged在普通布局中不会被调用
parent CoordinatorLayout
child 拥有此Behavior属性的view
dependency 可以理解成为一个锚点,child以dependency为锚点
如果Behavior需要改变此子View的大小or位置,则返回true

onDependentViewRemoved方法

dependency被移除的时候调用的方法,参数作用和上面的一致

onLayoutChild方法

CoordinatorLayout绘制child的时候调用
parent 同上
child 同上
layoutDirection  CoordinatorLayout布局解析的方法 0=ltr 1=rtl,因为有些国家是从左向右显示的

onStartNestedScroll方法

开始滑动的时候调用一次,手松开的时候调用一次
返回true代表获取滑动事件,其他的scroll事件就会被触发
coordinatorLayout
child 使用此Behavior的View
directTargetChild 是target或是target的parent
target 处理滑动事件的view
axes  垂直滚动2 横向滚动1
type  滑动类型touch 0手指按下 1手指松开

onNestedScrollAccepted方法

dependencyView接受到触摸事件的时候调用一次

onStopNestedScroll方法

手指松开时,调用一次,滑动停止时调用一次

onNestedScroll方法

页面滑动的时候调用
coordinatorLayout 同上
child 同上
target 同上
dxConsumed 水平滑动的实时距离
dyConsumed 竖直滑动的实时距离
dxUnconsumed view处于滚动状态,但是并不是由target消耗的滚动时候触发,这个是水平滚动的实时距离
dyUnconsumed view处于滚动状态,但是并不是由target消耗的滚动时候触发,这个是竖直滚动的实时距离
type 同上

onNestedPreScroll方法

在target已消耗任何滚动距离之前,正在进行嵌套滚动更新时调用
coordinatorLayout 同上
child 同上
target 同上
dx 同上
dy 同上
consumed consumed[0]为消耗的x距离,consumed[1]为消耗的y距离
type 同上

onNestedFling方法

滑动时手指松开如果还继续滑动的时候调用一次
coordinatorLayout 同上
child 同上
target 同上
velocityX 水平加速度
velocityY 竖直加速度
consumed 同上
false不拦截 true则不会有惯性滑动,需要自己处理

onNestedPreFling方法

和onNestedFling一样,只不过会优先于onNestedFling方法调用
大致就这些方法了,当然还有Touch的一些方法,用法是一样的,想想要不要举个栗子。。。


©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页