Android CoordinatorLayout和Behavior的源码分析(二)
2017-06-16 18:57
387 查看
2. Behavior如何进行代理的
我们按照以下三种情况分析如何用Behavior进行代理的:2.1 子view依赖子view状态变化
2.2 嵌套滑动
2.3 Behavior拦截一切事件
具体调用Behavior的方法对应如下:
2.1
public boolean layoutDependsOn(CoordinatorLayout parent, V child, View dependency) { return false; } public boolean onDependentViewChanged(CoordinatorLayout parent, V child, View dependency) { return false; }
2.2
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, V child, View directTargetChild, View target, int nestedScrollAxes) { return false; } public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, V child, View target, int dx, int dy, int[] consumed) { // Do nothing } public boolean onNestedFling(CoordinatorLayout coordinatorLayout, V child, View target, float velocityX, float velocityY, boolean consumed) { return false; }
2.3
public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent ev) { return false; } public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent ev) { return false; }
2.1
layoutDependsOn和OndependentViewChanged调用过程
一个view随着另一个view的拖动向反方向移动这种效果,是通过重写Behavior的下面两个方法实现的:@Override public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) { return dependency instanceof TempView; } @Override public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) { int top = dependency.getTop(); int left = dependency.getLeft(); int x = width - left - child.getWidth(); int y = top; setPosition(child, x, y); return true; } private void setPosition(View v, int x, int y) { CoordinatorLayout.MarginLayoutParams layoutParams = (CoordinatorLayout.MarginLayoutParams) v.getLayoutParams(); layoutParams.leftMargin = x; layoutParams.topMargin = y; v.setLayoutParams(layoutParams); }
那我看下为什么实现layoutDependsOn和OndependentViewChanged是怎么被调用的:
View.measure CoordinatorLayout.onMeasure CoordinatorLayout.ensurePreDrawListener CoordinatorLayout.hasDependencies CoordinatorLayout.addPreDrawListener CoordinatorLayout.dispatchOnDependentViewChanged CoordinatorLayout$LayoutParams.dependsOn Dependent2Behavior.layoutDependsOn
我们详细看下dispatchOnDependentViewChanged方法:
void dispatchOnDependentViewChanged(final boolean fromNestedScroll) { ... // Update any behavior-dependent views for the change for (int j = i + 1; j < childCount; j++) { .... if (b != null && b.layoutDependsOn(this, checkChild, child)) { ... final boolean handled = b.onDependentViewChanged(this, checkChild, child); .... } } }
每次重绘时,dispatchOnDependentViewChanged会判断是否依赖,如果依赖,就去根据自己的需要,对child进行移动或者其他处理。
2.2
onStartNestedScroll和onNestedPreScroll实现原理
父view嵌套子view滑动,上滑时,先滑动父view,子view随着动,向下滑动时,先滑动子view,再滑动父view这种效果的实现,是嵌套滑动,通过重写Behavior的下面的方法实现:@Override public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) { return true; } @Override public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) { offset(child, dyConsumed); } 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; }
为了方便理解,我们全面理解一下嵌套滑动机制(NestedScroll)。
相关文章推荐
- Android CoordinatorLayout和Behavior的源码分析(四)
- Android CoordinatorLayout和Behavior的源码分析(三)
- Android CoordinatorLayout和Behavior的源码分析(一)
- Android 一步一步分析CoordinatorLayout.Behavior
- CoordinatorLayout自定义Behavior&源码分析
- [Android Design Lib]CoordinatorLayout源码分析
- CoordinatorLayout自定义Bahavior特效及其源码分析
- Android应用开发原理之从源码分析看Linearlayout、Relativelayout,Framelayout的布局差别(Relativelayout分析)
- Android应用setContentView与LayoutInflater加载解析机制源码分析
- Android的LinearLayout源码分析
- Android LayoutInflater源码分析及使用(一)
- android view layout源码分析
- Android中将xml布局文件转化为View树的过程分析(下)-- LayoutInflater源码分析
- Material Design风格中CoordinatorLayout、Behavior和nestedScroll的整理分析
- <Android 基础(二十)> CoordinatorLayout Behavior
- Android应用setContentView与LayoutInflater加载解析机制源码分析
- Android应用setContentView与LayoutInflater加载解析机制源码分析
- Android View系统源码分析(十三)—— View.requestFocus() & ViewRoot.requestLayout()
- 开源中国 OsChina Android 客户端源码分析(2)滑动菜单DrawerLayout
- Android应用setContentView与LayoutInflater加载解析机制源码分析(转载)