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

不废话,先看效果

这里写图片描述

思路

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值