仿product hunt 头像收起展开的效果

不废话,先看效果

仿product hunt 头像收起展开的效果_第1张图片

思路

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;
    }

源码

GitHub

你可能感兴趣的:(滑动动画,product-hu)