先看代码:
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
final int leftBound = getPaddingLeft();
final int rightBound = getWidth() - mDragView.getWidth();
final int newLeft = Math.min(Math.max(left, leftBound), rightBound);
return newLeft;
}
从字面意思就可以看出这是一个获取边界的方法,先看代码。
@Override
public int getViewVerticalDragRange(View child) {
return mDragRange;
}
然后看看mDragRange是怎么赋值的:
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mDragRange = getHeight() - mHeaderView.getHeight();
}
所以很清楚了,范围值在最初测量摆放子view时,在onLayout方法就已经确定了。
确定当前子view是否可拖动,用法很简单。看看代码:
@Override
public boolean tryCaptureView(View child, int pointerId) {
return child == mHeaderView;
}
这段代码表明只有当view是mHeaderView才可以拖动,其他子View都不可拖动。
该方法在子view位置发生改变时都会被调用,可以在这个方法中做一些拖动过程中渐变的动画等操作,看看代码:
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
mTop = top;
mDragOffset = (float) top / mDragRange;
mHeaderView.setPivotX(mHeaderView.getWidth());
mHeaderView.setPivotY(mHeaderView.getHeight());
mHeaderView.setScaleX(1 - mDragOffset / 2);
mHeaderView.setScaleY(1 - mDragOffset / 2);
mDescView.setAlpha(1 - mDragOffset);
requestLayout();
}
这段代码的意思是mHeaderView随着Y轴方向的位置变化做缩放,mDescView随着Y轴方向的位置变化做渐变,然后重绘界面。
该方法在手势拖动释放的时候被调用,可以在这里设置子View预期到达的位置,如果人为的手势拖动没有到达预期位置,我们可以让子View在人为的拖动结束后,再自动关的滑动到指定位置,看看代码:
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
int top = getPaddingTop();
if (yvel > 0 || (yvel == 0 && mDragOffset > 0.5f)) {
top += mDragRange;
} mDragHelper.settleCapturedViewAt(releasedChild.getLeft(), top);
invalidate();
}
这段代码的意思是当人为的拖动结束后,如果没有到达顶部,则设置view自动滑动到顶部。
当然在onViewReleased()方法中还可以做一些其他的后续操作。
该方法很好理解了,就是当你触碰到边界时就会被调用。
前提是已经在DragHelper中设置了开启边界使用的模式,都则该方法不会被掉起,设置开启边界模式代码如下:
dragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
这就算开启了左侧边界模式
前提是已经在DragHelper中设置了开启边界使用的模式,都则该方法不会被掉起,设置开启边界模式代码如下:
dragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
这就算开启了左侧边界模式
该方法比较有意思,当人为的从边界拖动(此时并没有拖动子view)时,可以选择关联某一个子view,实现只要从边界拖动,不管是否触碰到子view,都能控制子view一起拖动的效果,看看代码:
@Override
public void onEdgeDragStarted(int edgeFlags, int pointerId) {
super.onEdgeDragStarted(edgeFlags, pointerId);
dragHelper.captureChildView(mDragView, pointerId);
}
相当于把mDragView传递给了dragHelper,让mDragView关联到从边界开始的拖动。