学Android Coordinatorlayout自定义Behaviorandroid高仿知乎首页Behavior
Android Coordinatorlayout定义Behavior
自定义Behavior的艺术探索-仿UC浏览器主页
SheHuan/BehaviorDemo
Behavior下滑隐藏上滑显示
Recyclerview实现滑动隐藏搜索布局下降显示搜索布局
自定义Behavior实现上滑和下滑
Behavior下滑隐藏上滑显示
自定义Behavior原理
Behavior自定义
自定义Behavior的高级玩法
Behavior自定义高级UI-
getx是Android开发的,getRawX,getWidth,getttranslationX等的区别
提供几种重要的方法layoutDependsOnonDependentViewChangedonStartNestedScrollonNestedScrollAcceptedonNestedPreScrollonNestedScrollonStopNestedScrollonNestedPreFlingonLayoutChild
layoutDependsOnlayoutDepentsOn, 至少调用一次, 用来判断Coordinatorlayout下的dependency是否是我们指定的依赖.
onDependentViewChanged如果上述方法返回true, coordinatorlayout将不断调用ondendentviewchanged()方法
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); } }}