Andoid高级-自定义Behavior

资料

学习Android CoordinatorLayout之自定义Behavior
Android高仿知乎首页Behavior
Android CoordinatorLayout之自定义Behavior
自定义Behavior的艺术探索-仿UC浏览器主页
SheHuan/BehaviorDemo
下滑隐藏上滑显示的Behavior
RecyclerView实现上滑动隐藏搜索布局下滑显示搜索布局
自定义Behavior实现上滑下滑那些事
下滑隐藏上滑显示的Behavior
自定义Behavior原理
自定义Behavior
高级玩法之自定义Behavior
高级UI-自定义Behavior

Android开发之getX,getRawX,getWidth,getTranslationX等的区别

在这里插入图片描述

提供几个重要方法

layoutDependsOn
onDependentViewChanged
onStartNestedScroll
onNestedScrollAccepted
onNestedPreScroll
onNestedScroll
onStopNestedScroll
onNestedPreFling
onLayoutChild

layoutDependsOn

layoutDepentsOn, 至少会调用一次, 用于判断CoordinatorLayout下的dependency是否是我们指定的依赖.

onDependentViewChanged

上面方法返回true的话, CoordinatorLayout会不断调用onDependentViewChanged()方法来

onStartNestedScroll

用户按下手指时触发,NSChild传过来一些参数,例如Y向滑动,询问NSParent是否要处理这次滑动操作。检查该方法下的预设条件,发现就是我们要处理的方向,则返回 true ,表示“我要处理这次滑动”,如果检查预设条件发现不是,例如预设的是X方向,返回 false, 表示“我不 care 你的滑动,你想咋滑就咋滑”,后面的一系列回调函数就不会被调用了。

onNestedScrollAccepted

当 NSParent 接受要处理本次滑动后,这个回调被调用,我们可以做一些准备工作,比如让之前的滑动动画结束。

onNestedPreScroll

当 NSChild即将被滑动时调用,在这里你可以为子View做一些处理。值得注意的是,这个方法有一个参数 int[] consumed,你可以修改这个数组来表示子View到底消费掉了多少像素。假设用户滑动了 100px,你让子View做了 90px 的位移,那么就需要把 consumed[1] 改成 90(下标 0、1 分别对应 x、y 轴),这样 NSChild 就能知道,然后继续处理剩下的 10px。

onNestedScroll

上一个方法结束后,NSChild 处理剩下的距离。比如上面还剩 10px,这里 NSChild 滚动 2px 后发现已经到头了,于是 NSChild 结束其滚动,调用该方法,并将 NSChild 处理剩下的像素数作为参数(dxUnconsumed、dyUnconsumed)传过来,这里传过来的就是 8px。参数中还会有 NSChild 处理过的像素数(dxConsumed、dyConsumed)。这个方法主要处理一些越界后的滚动。

onStopNestedScroll

用户松开手指并且会发生惯性滚动之前调用。参数提供了速度信息,我们这里可以根据速度,决定最终的状态是展开还是折叠,并且启动滑动动画。通过返回值我们可以通知 NSChild 是否自己还要进行滑动滚动,一般情况如果面板处于中间态,我们就不让 NSChild 接着滚了,因为我们还要用动画把面板完全展开或者完全折叠。

onNestedPreFling

一切滚动停止后调用,如果不会发生惯性滚动,fling 相关方法不会调用,直接执行到这里。这里我们做一些清理工作,当然有时也要处理中间态问题。

onLayoutChild

满足的代码

public class ChangeOffsetYBehavior extends CoordinatorLayout.Behavior {


    private float mOffsetY = -1;

    public ChangeOffsetYBehavior() {
    }

    public ChangeOffsetYBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    @Override
    public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) {
        return (axes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;
    }

    @Override
    public void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) {
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
        if (target instanceof RecyclerView) {
            float saveHeigth = 0;
            if (child instanceof LinearLayout) {
                View childAt = ((LinearLayout) child).getChildAt(((LinearLayout) child).getChildCount() - 1);
                saveHeigth = childAt.getHeight();
            }

            float total = /*params.bottomMargin +*/ child.getHeight() - saveHeigth;
            // 需要留下的宽度

            mOffsetY += dy;
            if (mOffsetY < 0) {
                mOffsetY = 0;
            }
            if (mOffsetY > total) {
                mOffsetY = total;
            }
            child.setTranslationY(-mOffsetY);
        }
    }
}
发布了167 篇原创文章 · 获赞 62 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/AdrianAndroid/article/details/101671887