Android开发 之 (协调布局)CoordinatorLayout与(依赖行为)Behavior

CoordinatorLayout与Behavior

翻译过来就是协调布局和依赖行为,这两个是内部类关系

在我这里有两种用途:看效果
Android开发 之 (协调布局)CoordinatorLayout与(依赖行为)Behavior_第1张图片

第一种,两个空间的y坐标形成依赖关系,坐标依赖


Android开发 之 (协调布局)CoordinatorLayout与(依赖行为)Behavior_第2张图片
第二种,滑动以来关系

上代码:
第一种:



    
    

当然了这种效果是基于协调布局开发的,所以布局必须使用协调布局
代码中button添加一个属性layout_behavior就是建立以来关系的属性,MyBehavior这个类是自定义的,这里属性值:自定义的类的包名+类名。

自定义的MyBehavior类:
package com.example.zxq.bsquxian.views;

import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;

/**
 * Created by Administrator on 2017/7/25 0025.
 */

public class MyBehavior extends CoordinatorLayout.Behavior
在上面的layoutDependsOn方法中判断依赖对象,要依赖到哪个组件上。这里依赖了一个自定义TextView,当然这里也可以通过id判断依赖关系

自定义的TextView:
package com.example.zxq.bsquxian.views;

import android.content.Context;
import android.support.annotation.Nullable;
import android.support.design.widget.CoordinatorLayout;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.TextView;

/**
 * Created by Administrator on 2017/7/25 0025.
 */

public class ScrPositionTextView extends android.support.v7.widget.AppCompatTextView {
    private int startx;
    private int starty;
    public ScrPositionTextView(Context context) {
        super(context);
    }

    public ScrPositionTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public ScrPositionTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                startx= (int) event.getRawX();
                starty= (int) event.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                int lastX= (int) event.getRawX();
                int lastY= (int) event.getRawY();
                int movex= lastX-startx;
                int movey= lastY-starty;
                startx= lastX;
                starty= lastY;
                CoordinatorLayout.MarginLayoutParams layoutParams= (CoordinatorLayout.MarginLayoutParams) getLayoutParams();
                int left = layoutParams.leftMargin+movex;
                int top = layoutParams.topMargin+movey;
                layoutParams.leftMargin=left;
                layoutParams.topMargin=top;
                setLayoutParams(layoutParams);
                requestFocus();
                break;
        }
        return true;
    }
}
这里动态改变textview的位置就ok,自己的y坐标会自动关联到那个button上去的。



第二种代码:
Behavior最大的用处在于对滑动事件的处理。就像CollapsingToolbarLayout的那个酷炫效果一样。
自定义的Behavior:这里需要重写以下几个方法

package com.example.zxq.bsquxian.views;

import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by Administrator on 2017/7/27 0027.
 */

public class ScrollBehavior extends CoordinatorLayout.Behavior {
    int offsetTotal = 0;
    boolean scrolling = false;

    public ScrollBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
        return true;//这里返回true,才会接受到后续滑动事件。
    }

    @Override
    public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
        //进行滑动事件处理
        offset(child,dyConsumed);
    }

    @Override
    public boolean onNestedFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY, boolean consumed) {
        //当进行快速滑动
        return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed);
    }

    @Override
    public boolean onInterceptTouchEvent(CoordinatorLayout parent, View child, MotionEvent ev) {
        return super.onInterceptTouchEvent(parent, child, ev);
    }

    @Override
    public boolean onTouchEvent(CoordinatorLayout parent, View child, MotionEvent ev) {
        return super.onTouchEvent(parent, child, ev);
    }

    public void offset(View child,int dy){
        int old = offsetTotal;
        int top = offsetTotal - dy;
        top = Math.max(top, -child.getHeight());
        top = Math.min(top, 0);
        offsetTotal = top;
        if (old == offsetTotal){
            scrolling = false;
            return;
        }
        int delta = offsetTotal-old;
        child.offsetTopAndBottom(delta);
        scrolling = true;
    }

}

布局文件;


    

        

            
        
    

    



注意被依赖的View只有实现了NestedScrollingChild接口的才可以将事件传递给CoordinatorLayout。
但注意这个滑动事件是对于CoordinatorLayout的。所以只要CoordinatorLayout有NestedScrollingChild就会滑动,他滑动就会触发这几个回调。无论你是否依赖了那个View。
Imageview设置关联属性

有关自己的事件处理可以在这2个回调与View中的事件分发是一样的。所有Behavior能在子View之前收到CoordinatorLayout的所有触摸事件。可以进行拦截,如果拦截事件将不会流经子View。因为这2个方法都是在CoordinatorLayout的 回调中

其实之前讲的AppBarLayout效果也是这个原理:
AppBarLayout自带一个Behivior。直接在源码里注解声明的。这个Behivior也只能用于AppBarLayout。
作用是让他根据CoordinatorLayout上的滚动手势进行一些效果(比如收缩)。与ScrollingViewBehavior是无关的,加不加ScrollingViewBehavior不影响收缩。
只不过只有某些可滑动View才会把滑动事件响应给CoordinatorLayout才能继而响应给AppBarLayout。

你可能感兴趣的:(Android,特效,Android,组件)