CoordinateLayout中自定义Behavior

Android自带的Behavior是AppBarLayout.ScrollingViewBehavior,对应的xml中的app:layout_behavior="@string/appbar_scrolling_view_behavior"属性。
我们可以自定义Behavior实现各个view和组件的交互和滑动。

有俩种方法

  • 1.定义的view来监听CoordinateLayout中的滑动状态。
  • 2.定义的view1来监听另外一个view2的状态变化,比如view2的大小,高度,位置变化,滑动状态等等。

具体处理

第1种

重写onStartNestedScroll()onNestedPreScroll()方法

第2种

重写layoutDependsOn()onDependentViewChanged()方法。


效果示例

CoordinateLayout中自定义Behavior_第1张图片
1图.view来监听CoordinateLayout中的滑动状态
CoordinateLayout中自定义Behavior_第2张图片
2图.view1来监听另外一个view2的状态变化

虽然看起来效果差不多,但是俩个图的实现原理是不一样的。


方法1:view来监听CoordinateLayout中的滑动状态实现方法

1.布局文件




    

        
    

    

    

        
    


2.新建一个类BehaviorForCoordinatorScroll继承自CoordinatorLayout.Behavior,重写onStartNestedScroll()onNestedPreScroll()方法:

  • onStartNestedScroll():它的返回值代表本次滑动要不要关心
  • onNestedPreScroll():用于处理具体滑动逻辑,它的dx,dy参数分别代表了水平滑动和垂直滑动的距离,比如dy上滑为正,根据其来确定view滑动的具体逻辑
import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewPropertyAnimator;

/**
 * 自定义监听
 * Created by Niwa on 2017/8/16.
 */

public class BehaviorForCoordinatorScroll extends CoordinatorLayout.Behavior {

    /**
     * 滑动距离累加值
     */
    private int directionChange = 0;

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

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
        //返回值表明这次滑动我们要不要关心,这里关心的是Y轴方向上的
        return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;
    }

    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) {
        if (dy > 0 && directionChange < 0 || dy < 0 && directionChange > 0) {

            child.animate().cancel();
            Log.e("CustomBehavior1", "reset");
            //dy是一直刷新的,累加值会一直加到很大或者很小,这里累加值归零0的触发条件是
            // 1.向上滑,并且累加值是负的(说明上次滑动是向下)
            //2.向下滑,并且累加值是正的(说明上次滑动是向上)
            directionChange = 0;
        }
        directionChange += dy;
        Log.e("CustomBehavior1", "dy:" + dy);
        Log.e("CustomBehavior1", "directionChange:" + directionChange);

        if (directionChange > child.getHeight()) {
            Log.e("CustomBehavior1", "上滑");
            hide(child);
        }
        if (directionChange < 0) {
            Log.e("CustomBehavior1", "下滑");
            show(child);
        }
    }

    private void show(final View child) {
        final ViewPropertyAnimator animator = child.animate()
                .translationY(0)
                .setInterpolator(new FastOutSlowInInterpolator())
                .setDuration(200);
        animator.start();
    }

    private void hide(final View child) {
        final ViewPropertyAnimator animator = child.animate()
                .translationY(child.getHeight())
                .setInterpolator(new FastOutSlowInInterpolator())
                .setDuration(200);
        animator.start();
    }

}

方法2:view1来监听另外一个view2的状态变化实现方法

1.新建一个类BehaviorForViewStateScroll继承自CoordinatorLayout.Behavior,把布局文件中的属性改为这个类app:layout_behavior="com.minminaya.behaviordemotest.behavior.BehaviorForViewStateScroll"

重写layoutDependsOn()onDependentViewChanged()方法:

layoutDependsOn():用来返回我们需要关心的类
onDependentViewChanged():根据我们关心的View的变化处理具体目的view处理逻辑


import android.content.Context;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewPropertyAnimator;

/**
 * 自定义监听
 * Created by Niwa on 2017/8/16.
 */

public class BehaviorForViewStateScroll extends CoordinatorLayout.Behavior {


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

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
        return dependency instanceof AppBarLayout;
    }

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
         //具体逻辑,获取当前的AppBarLayout的可见部分的y轴坐标大小
        float transitionY = Math.abs(dependency.getY());
        //目的view设置变化
        child.setTranslationY(transitionY);
        //表明已处理事件
        return true;
    }
}

注意事项

  • 一定不要漏了自定义Behavior中的构造函数!!!!!!
  • 注意动画的使用如果不及时停止可能会导致内存泄露从而闪退

end

你可能感兴趣的:(CoordinateLayout中自定义Behavior)