仿饿了么横向列表滑动释放查看更多

这里接着上一篇文章 通过NestedScrolling实现RecyclerView拖拽回弹效果,做了一些优化并增加滑动动画效果。

首先看下我们要实现的效果:


仿饿了么横向列表滑动释放查看更多_第1张图片
饿了么效果
仿饿了么横向列表滑动释放查看更多_第2张图片
我们的效果

功能很简单,需要给RecyclerView做两个扩展:

一、增加拖拽功能

拖拽功能在上一章已经做了介绍,但有几点需要注意:

1、拖拽范围限制

    @Override
    public void scrollTo(int x, int y) {
        if (x < 0) {
            x = 0;
        } else if (x > maxWidth * 2) {
            x = maxWidth * 2;
        }
        super.scrollTo(x, y);
    }

2、惯性问题:当RecyclerView在界面之内交给它自己惯性滑动

    @Override
    public boolean onNestedPreFling(View target, float velocityX, float velocityY) {
        // 当RecyclerView在界面之内交给它自己惯性滑动
        return getScrollX() != maxWidth;
    }

3、快速左右连续滑动会出现错位问题,需要要限制处理

@Override
    public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
        ...

        // 限制错位问题
        if (dx > 0 && getScrollX() > maxWidth && !ViewCompat.canScrollHorizontally(target, -1)) {
            scrollTo(maxWidth, 0);
        }
        if (dx < 0 && getScrollX() < maxWidth && !ViewCompat.canScrollHorizontally(target, 1)) {
            scrollTo(maxWidth, 0);
        }
    }

4、动画问题:和惯性同样判断什么时候开启动画

    @Override
    public void onStopNestedScroll(View target) {
        mParentHelper.onStopNestedScroll(target);
        // 如果不在RecyclerView滑动范围内
        if(maxWidth != getScrollX()){
            startAnimation(new ProgressAnimation());
        }
    }

5、多点触控问题:在动画执行时期不处理事件

    @Override
    public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
        return target instanceof RecyclerView && !isRunAnim;
    }

    mChildView.setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    // 保证动画状态中 子view不能滑动
                    return isRunAnim;
                }
    });

二、根据拖拽距离绘制椭圆

1、首先要保证查看更多按钮一直在最右边显示
有两个思路:
(1)自定义扩展得View宽度固定,查看更多按钮位置随着滑动距离变化。
(2)自定义扩展的View宽度随着滑动距离变化,查看更多按钮右居中显示。

2、滑动显示出更多按钮后,开始绘制椭圆。

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPath.reset();
        float marginTop = (mHeight - mLayoutHeight) / 2;
        // 右上角x坐标、右上角y坐标
        mPath.moveTo(mMove - mLayoutWidth, marginTop);
        // 左边弧形x坐标、左边弧形y坐标、右下角x坐标、右下角y坐标
        mPath.quadTo(0,  mHeight / 2, mMove - mLayoutWidth, mLayoutHeight + marginTop);
        canvas.drawPath(mPath, mBackPaint);
    }

demo地址:https://github.com/eatdefecat/DZStickyNavLayout

最后还有个问题很困扰我,如果没有给RecyclerView中itemView设置可以点击,onStartNestedScroll会执行2次,并且onNestedPreScroll方法里返回的dx或者dy会变得很大,实现不了阻力效果。如果有知道这是什么原因引起的欢迎在文章下面留言。

你可能感兴趣的:(仿饿了么横向列表滑动释放查看更多)