不废话,先看效果
思路
view连接view,在没有距离的时候,可以认为是坐标轴为0的时候 view重叠view的时候,可以认为是坐标轴-1的时候
view展开的时候,可以认为坐标轴为1的时候
动画的实现,通过onlayout中space的大小完成view的展开和重叠
ViewDragHelper
如果你还不了解ViewDragHelper,可以先看我之前写的几篇讲ViewDragHelper入门的文章
ViewDragHelper几个方法的理解
ViewDragHelper.CallBack中每个方法的用法
ViewDragHelper详解
主要代码部分
private class DragHelperCallback extends ViewDragHelper.Callback {
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
// 按比例计算滑动的位移,在maxSpace和minSpace之间
int minLeft = getCurrentViewLeft(changedView);
int maxRight = getCurrentViewRight(changedView);
int step = maxRight - minLeft;
int halfStep = step / 2;
int byOriginValue = left - (minLeft + maxRight) / 2;
double spaceValue = byOriginValue * 1.0 / halfStep * maxSpace;
mDragOffset = byOriginValue * 1.0 / halfStep;
space = (int) spaceValue;
if (space > maxSpace) {
space = maxSpace;
}
if (space < minSpace) {
space = minSpace;
}
if (listener != null) {
listener.onSlide(mDragOffset);
}
requestLayout();
}
@Override
public boolean tryCaptureView(View child, int pointerId) {
return true;
}
@Override
public int getViewVerticalDragRange(View child) {
return mVerDragRange;
}
@Override
public int getViewHorizontalDragRange(View child) {
return mHorDranRange;
}
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
// 在释放滑动事件后,继续移动view,达到惯性的效果
int right = 0;
if (mDragOffset - mDragOffsetLast > 0) {
right = getCurrentViewRight(releasedChild);
mDragHelper.settleCapturedViewAt(right, 0);
invalidate();
mDragOffsetLast = 1;
} else {
right = getCurrentViewLeft(releasedChild);
mDragHelper.settleCapturedViewAt(right, 0);
invalidate();
mDragOffsetLast = -1;
}
}
// 判断滑动的边界,不能出界
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
final int newLeft = Math.min(Math.max(left, getCurrentViewLeft(child)), getCurrentViewRight(child));
return newLeft;
}
}
// 探测子View的右边界
private int getCurrentViewRight(View view) {
int index = indexOfChild(view);
int right = view.getWidth() * index + index * maxSpace;
return right;
}
// 探测子View的左边界
private int getCurrentViewLeft(View view) {
int index = indexOfChild(view);
int left = view.getWidth() * index + index * minSpace;
return left;
}
// 让动画持续
@Override
public void computeScroll() {
if (mDragHelper.continueSettling(true)) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
// 指定滑动到某个位置
private boolean smoothSlideTo(float slideOffset) {
int right = slideOffset == 0f ? getCurrentViewLeft(mRightView) : getCurrentViewRight(mRightView);
if (mDragHelper.smoothSlideViewTo(mRightView, right, 0)) {
ViewCompat.postInvalidateOnAnimation(this);
return true;
}
return false;
}