拿來就可以用,帶header view的ScrollView

預(yù)期效果

類似魅族便簽下拉顯示標(biāo)題的效果,加入了顯示隱藏的動畫。

實(shí)現(xiàn)

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()即當(dāng)前滑動的距離與header View高度的比較,并設(shè)定一個閾值,當(dāng)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;

                    //這里要確保點(diǎn)擊事件不失效
                    //we force stop scroll when touch down
                    //in some case we need to finish scroll up or down
                    if (currentPage == PAGE_TOP) {
                        //下面的判斷已經(jīng)能確定用戶是否往上滑
                        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設(shè)置粘性滑動(有沒有更貼切的名字?) 即scrollview的滑動不跟隨手指的滑動,假如設(shè)置的比值為0.4,那么手指滑動10個像素,實(shí)際scrollview只滑動了4個像素,類似下拉刷新的那種下拉吃力的感覺。實(shí)現(xiàn)方法很簡單,在TouchEvent中,通過scrollBy()方法實(shí)現(xiàn)scrollview的滑動,并返回true,表示scrollview消費(fèi)了該次事件。

  @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (isInIgnoredView(ev)) {
            Log.e(TAG, "onTouchEvent>>不消費(fèi)事件");
            return false;
        } else {
            Log.e(TAG, "onTouchEvent>>消費(fèi)事件");
            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...歡迎吐槽...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,034評論 25 709
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,309評論 4 61
  • 一個人的時候,我喜歡走夜晚的街道,看著馬路上來來往往的車輛,借著點(diǎn)點(diǎn)稀疏的燈光,感覺自己在燈火斑斕的城市...
    墨欣閱讀 351評論 0 0
  • 坐暮色里, 聽風(fēng), 掠過樹梢的蕭蕭, 朧朦的深處, 蛙鳴,歌唱著神秘的夜黑。 這個時候, 我和樹影保持同一種顏色,...
    詩與遠(yuǎn)方工作室閱讀 185評論 0 1
  • -*- vim環(huán)境設(shè)置 -*- 經(jīng)常使用vim時 會有一些基礎(chǔ)的環(huán)境設(shè)置便于我們更好的使用vim編輯器! 首先 ...
    DOVE_5214閱讀 236評論 0 0

友情鏈接更多精彩內(nèi)容