仿知乎详情页

仿知乎详情页

项目需求要求详情页仿照知乎来,从网上扒拉了很长时间,没找到十分合适的,就找了个有相似功能的改了改,感觉还可以,分享下给大家。

主要功能就是当前页的最后展示下一页的一半内容,上拉可以看到部分内容,最后上拉有个viewpager的切换效果,不过改成了上下切换。下拉就是上一页。最难的部分还是在自定义的scrollview上,需要处理里面的各种onTouch事件,费时费力,真是不好做,不过思路基本就是这样吧,不知道知乎原开发者咋写的。

BounceScrollView

重写scrollview来实现。onTouchEvent方法

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (mChildView == null || mDisableBounce)
            return super.onTouchEvent(ev);

        // 默认active的Index
        int actionIndex = ev.getActionIndex();

        switch (ev.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                mScrollPointerId = ev.getPointerId(0);
//                Log.e("tenda", "ACTION_DOWN firstPointId:" + firstPointId);
                mStart = isHorizontal ? ev.getX() : ev.getY();
                onePointerTouch = true;
                towPointerTouch = false;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                //第二个手指按下
//                Log.e("tenda", "ACTION_POINTER_DOWN getPointerCount:" + ev.getPointerCount());
                if (ev.getPointerCount() <= 2) {
                    mScrollPointerId = ev.getPointerId(actionIndex);
                    mStart = isHorizontal ? ev.getX(mScrollPointerId) : ev.getY(mScrollPointerId);
//                    Log.e("tenda", "ACTION_POINTER_DOWN secondPointId:" + secondPointId + " firstPointId:" + firstPointId);
                    onePointerTouch = false;
                    towPointerTouch = true;
                } else {
                    cancelTouch();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                float now, delta;
                float dampingDelta;

                // 通过pointerID拿到需要处理的Index。
                final int index = ev.findPointerIndex(mScrollPointerId);
                if (index < 0) {
                    Log.e("BounceScrollView", "Error processing scroll; pointer index for id "
                            + mScrollPointerId + " not found. Did any MotionEvents get skipped?");
                    return false;
                }

                now = isHorizontal ? ev.getX(index) : ev.getY(index);
                delta = mStart - now;
                dampingDelta = (delta / calculateDamping());
                mStart = now;

                if (mPreDelta <= 0 && dampingDelta > 0) {
                    onePointerTouch = false;
                } else if (mPreDelta >= 0 && dampingDelta < 0) {
                    onePointerTouch = false;
                } else {
                    onePointerTouch = true;
                }
                mPreDelta = dampingDelta;
//                Log.e("tenda", "delta:" + delta + "dampingDelta:" + dampingDelta);
                if (onePointerTouch && canMove(dampingDelta)) {
                    mOverScrolledDistance += dampingDelta;
//                    Log.e("tenda", "canMove true mOverScrolledDistance:" + mOverScrolledDistance);
                    if (isLoad) {
                        if (mOverScrolledDistance >= 500) {
                            mOverScrolledDistance = 500;
                        }
                        if (getScrollY() == 0) {
                            //已经到最顶部
                            break;
                        }
                    }
                    if (isPull) {
                        if (mOverScrolledDistance <= -200) {
                            mOverScrolledDistance = -200;
                        }
                        if (getScrollY() > 0) {
                            //已经到最底部
                            break;
                        }
                    }
                    if (isHorizontal) {
                        mChildView.setTranslationX(-mOverScrolledDistance);
                    } else {
                        mChildView.setTranslationY(-mOverScrolledDistance);
                    }
                    if (mOverScrollListener != null) {
//                        mOverScrollListener.onOverScrolling(mOverScrolledDistance <= 0, Math.abs(mOverScrolledDistance));
                        if (canMoveFromStart()) {
                            //下拉
                            isPull = true;
                            mOverScrollListener.onPulling(mOverScrolledDistance);
                        } else {
                            //上拉
                            isLoad = true;
                            mOverScrollListener.onOverScrolling(mOverScrolledDistance <= 0, mOverScrolledDistance);
                        }
                    }
                } else {
                    if (isLoad) {
//                        Log.e("tenda", "mPreDelta:" + mPreDelta + " dampingDelta:" + dampingDelta);
//                        Log.e("tenda", " isLoad * calculateDamping:" + calculateDamping());
                        dampingDelta = delta;
                        mOverScrolledDistance += dampingDelta;
//                        Log.e("tenda", "canMove false isLoad mOverScrolledDistance:" + mOverScrolledDistance);
                        mOverScrollListener.onOverScrolling(mOverScrolledDistance <= 0, mOverScrolledDistance);
                    } else if (isPull) {
//                        Log.e("tenda", "isPull * calculateDamping:" + calculateDamping());
                        dampingDelta = delta;
                        mOverScrolledDistance += dampingDelta;
//                        Log.e("tenda", "canMove false isPull mOverScrolledDistance:" + mOverScrolledDistance);
                        mOverScrollListener.onPulling(mOverScrolledDistance);
                    }
                }

                break;
            case MotionEvent.ACTION_UP:
                //最后一个手指松开
//                Log.e("tenda", "ACTION_UP");
                towPointerTouch = false;
                onePointerTouch = false;
                cancelTouch();
                break;
            case MotionEvent.ACTION_POINTER_UP:
                //第二个手指松开
                onPointerUp(ev);
                towPointerTouch = false;
                onePointerTouch = true;
                break;
            case MotionEvent.ACTION_CANCEL:
                onePointerTouch = true;
                towPointerTouch = false;
                cancelTouch();
                break;
        }

        return super.onTouchEvent(ev);
    }

在这里插入图片描述
项目地址:
https://github.com/tenda2014/ZhiHuDetail

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值