美文网首页android
拿来就可以用,带header view的ScrollView

拿来就可以用,带header view的ScrollView

作者: tse1y | 来源:发表于2017-11-21 16:37 被阅读12次

    预期效果

    类似魅族便签下拉显示标题的效果,加入了显示隐藏的动画。

    实现

    1、OnLayout中获取第一个子view的高度

        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            super.onLayout(changed, l, t, r, b);
            mChildLayout = (ViewGroup) getChildAt(0);
            mTopChildView = mChildLayout.getChildAt(0);
            topChildHeight = mTopChildView.getMeasuredHeight();
            screenHeight = getMeasuredHeight();
            offsetDistance = topChildHeight - screenHeight;
            if (!mInited) {
                mInited = true;
                if (currentPage == PAGE_BOTTOM) {
                    scrollTo(0, topChildHeight);
                }
            }
        }
    
    

    2、dispatchTouchEvent中在ACTION_UP时,通过getscrollY()即当前滑动的距离与header View高度的比较,并设定一个阈值,当getscrollY()大于或小于该阈值时,显示或隐藏header view。

    @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            if (isInIgnoredView(ev)) {
                //往下传递
                Log.e(TAG, "dispatchTouchEvent>>传递事件");
                return super.dispatchTouchEvent(ev);
            } else {
                Log.e(TAG, "dispatchTouchEvent>>不传递事件");
                switch (ev.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        isTouch = true;
                        downY = (int) ev.getY();
                        downTime = System.currentTimeMillis();
                        if (mScroller != null) {
                            mScroller.forceFinished(true);
                            mScroller = null;
                        }
                        break;
                    case MotionEvent.ACTION_MOVE:
    
                        break;
                    case MotionEvent.ACTION_UP:
                        isTouch = false;
                        upY = (int) ev.getY();
                        upTime = System.currentTimeMillis();
                        boolean isUpMove = upY - downY <= 0;//是否上划
                        //用户手指在屏幕上的时间
                        long duration = upTime - downTime;
    
                        //这里要确保点击事件不失效
                        //we force stop scroll when touch down
                        //in some case we need to finish scroll up or down
                        if (currentPage == PAGE_TOP) {
                            //下面的判断已经能确定用户是否往上滑
                            if (getScrollY() > offsetDistance) {
                                mScroller = new Scroller(mContext);
                                if (getScrollY() < (screenHeight * PERCENT + offsetDistance) && duration > TOUCH_DURATION) {
                                    //基本可以无视
                                    isPageChange = false;
                                    scrollToTarget(PAGE_TOP);
                                } else if (getScrollY() > topChildHeight / 5) {
                                    //切换到下界面 手势是上划且滑动的距离大于一定值
                                    isPageChange = true;
                                    scrollToTarget(PAGE_BOTTOM);
    
                                } else if (getScrollY() <= topChildHeight / 5) {
                                    isPageChange = false;
                                    scrollToTarget(PAGE_TOP);
                                } else if (getScrollY() > topChildHeight) {
                                    isPageChange = true;
                                    currentPage = PAGE_BOTTOM;
                                }
                                return false;
                            }
                        } else {
                            if (getScrollY() < topChildHeight) {
                                mScroller = new Scroller(mContext);
                                if (getScrollY() < topChildHeight / 2) {
                                    //切换到上界面
                                    isPageChange = true;
                                    scrollToTarget(PAGE_TOP);
                                } else {
                                    isPageChange = false;
                                    scrollToTarget(PAGE_BOTTOM);
                                }
                                return false;
                            }
                        }
    
                        break;
                }
            }
    
            return super.dispatchTouchEvent(ev);
        }
    

    3、header view设置粘性滑动(有没有更贴切的名字?) 即scrollview的滑动不跟随手指的滑动,假如设置的比值为0.4,那么手指滑动10个像素,实际scrollview只滑动了4个像素,类似下拉刷新的那种下拉吃力的感觉。实现方法很简单,在TouchEvent中,通过scrollBy()方法实现scrollview的滑动,并返回true,表示scrollview消费了该次事件。

      @Override
        public boolean onTouchEvent(MotionEvent ev) {
            if (isInIgnoredView(ev)) {
                Log.e(TAG, "onTouchEvent>>不消费事件");
                return false;
            } else {
                Log.e(TAG, "onTouchEvent>>消费事件");
                currentY = (int) ev.getY();
                switch (ev.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        lastY = (int) ev.getY();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        int moveY = currentY - lastY;
                        lastY = currentY;
                        if (currentPage == PAGE_BOTTOM) {
                            if (getScrollY() <= topChildHeight) {
                                //下拉
                                scrollBy(0, (int) (-moveY * mFraction));
                                return true;
                            } else {
                                return super.onTouchEvent(ev);
                            }
                        } else {
                            return super.onTouchEvent(ev);
                        }
                    case MotionEvent.ACTION_CANCEL:
                    case MotionEvent.ACTION_UP:
                        break;
                }
                return super.onTouchEvent(ev);
            }
        }
    

    4、动画。动画使用了属性动画,这里就不多介绍了。

    效果图

    gif太大..简书上传不了.
    偷偷懒,移步github看效果

    GitHub

    github源码

    欢迎star...欢迎吐槽...

    相关文章

      网友评论

        本文标题:拿来就可以用,带header view的ScrollView

        本文链接:https://www.haomeiwen.com/subject/vrgmvxtx.html