DrawerLayout
使用注意事项:
1 : 只能包含一个layout_gravity="start"或者layout_gravity="end"的子View;
2 : 布局分为left , right , 和 content, 因此需要一个content布局。
使用:
源码: onMeasure()
通过layoutparams的属性layout_gravity判断child是否是content还是child
如果是content,大小设置size 为 parentSize(比如1080), mode为Measure.Exactly。
如果是child , 设置宽度最大可用为parentSize - mMinDrawer- lp.leftmargin-lp.rightMargin,
设置高度最大可用 parentSize - lp.topMargin- lp.bottomMargin;
layout()过程:
1 content : child.layout(lp.leftMargin, lp.topMargin,lp.leftMargin + child.getMeasuredWidth(),lp.topMargin + child.getMeasuredHeight()); 没有考虑padding
2 leftChild : 找到left坐标。已Gravity.Top为例:
child.layout(childLeft, lp.topMargin, childLeft + childWidth,lp.topMargin + childHeight);
ViewDragHelper:
TryCaptureView() : 检测是否是left或者right child
onViewDragStateChanged() 分发拖拽,拖拽中,暂停状态。
onViewPositionChanged() move事件会回调这个方法,计算offset,然后invalute(),接着会调用computeScroll() 对leftchild或者rightchild滚动。
onViewCaptured() 当view捕获了。关闭另一侧的child;
dispatchViewReleased() up事件调用。判断当前child的offset是否大于0.5 ,关闭或者开启view;
onEdgeTouched() 当边缘被触摸的时候。
onEdgeDragStarted() 寻找和设置捕获的leftchild或者rightchild()
getViewHorizontalDragRange() 子view拖动的范围
clampViewPositionHorizontal() 水平方向子view的left值取值范围,最小为-childwidth ,最大为0;
clampViewPositionVertical() 竖直方向子view的top取值范围。
事件拦截:
public boolean onInterceptTouchEvent(MotionEvent ev) {
final boolean interceptForDrag =mLeftDragger.shouldInterceptTouchEvent(ev)
}
public boolean onTouchEvent(MotionEvent ev) {
mLeftDragger.processTouchEvent(ev);
mRightDragger.processTouchEvent(ev);
return true
}
SlidePanelLayout
使用注意事项:
1 : 只能包含2个子view .
2 : 第一个子view是左侧或者右侧的panel,第二个子view是SlideView, 两个子view的宽度必须大于parentSize;
3 : layoutDieection 控制panel显示在左侧还是右侧。 设置parallaxBy有视差效果。
onMeasure()过程:
寻找最大的高度,宽度最大取值为parentSize,测量过程有些繁琐。
这段代码可以简化成:
measureChildWithMargins(child,widthMeasureSpec,0,heightMeasureSpec,0);
测量2个child的高度,找最大的高度,宽度的最大值为parentSize - overhangSize(悬挂的尺寸);
setMeasuredDimension(sizeW,layoutHeight + getPaddingBottom() + getPaddingTop());
onLayout()过程
分为2种情况 : 设置了mParallaxBy,第一个子view的布局left = - mParallaxBy;
不设置mParallaxBy,第一个子View的布局left = 0; 此时2个布局是重叠在一起的。
ViewDragHelper和DrawerLayout里面的使用是一样的。
DrawerLayout和SliPanelLayout的不同之处:
onMeasure: drawerLayout的content部分的宽高是MATCH_PARENT的。 slidePanelLayout的content部分的宽为maxLimitWidth,高度为测量的最大高度,panel的测量方式相同。
onLayout: drawerLayout的panel和content不重叠的。SlidePanelLayout默认是重叠的。设置mParallaxBy,可以不重叠。
slideLayout的slideView是content,drawerLayout的slideView是左右的child。