4.4自定義狀態欄比5.0系統提供改變顏色的更棒(仿QQ個人資料效果)

好久沒寫博客了。直接上3圖看效果!!!!手機爲 oppo r7 android 系統4.4

   


話不多簡單代碼如下。。。。

核心api:!!只有4.4以上的系統纔有這特性,所以得判斷的喲!!

getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);


//下面我們開始處理邏輯了。。一般情況下。我們如果沒有用actionBar的話都會自定義一個高度用作標題欄。我也是這樣做的。

我們前面是做判斷>=19的。所以你就按照情況正常寫。通過動態改變控件的高度已經控制裏面內容顯示。。


搞定60%!!!!!接下來就需要一個能監聽滑動事件了。。。我是自定義的ScrollView。這個ScrollView 比較特別。也能做回彈效果。以後在將回彈吧。。這是自定義ScrollView

public class MyScrollView extends ScrollView {

    private OnScroll onScroll = null;

    private ScrollBottomListener scrollBottomListener;

    private ImageView mHeaderImg;

    private int mHeaderImgMaxHeight;

    private int mHeaderImgOriginalHeight;

    public MyScrollView(Context context) {
        super(context);
    }

    public MyScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        if (t + getHeight() >= computeVerticalScrollRange()) {
            if (scrollBottomListener != null) {
                scrollBottomListener.scrollBottom();
            }
        }
        /**
         * 滑動監聽
         */
        if (onScroll != null) {
            onScroll.onScrollChanged(l, t, oldl, oldt);
        }
    }


    public void setScrollBottomListener(ScrollBottomListener scrollBottomListener) {
        this.scrollBottomListener = scrollBottomListener;
    }

    /**
     * 是否滾動到底部
     */
    public interface ScrollBottomListener {
        public void scrollBottom();
    }

    public void setOnScrollStatus(OnScroll onScroll) {
        this.onScroll = onScroll;
    }

    public interface OnScroll {
        void onScrollChanged(int x, int y, int oldx, int oldy);
    }


    @Override
    /**
     * deltaY: 豎向滑動到頭的值: -值就是拉到頭了。+值就是拉到尾巴了
     * maxOverScrollY:結束後最大超過的值
     * isTouchEvent:是否按住拖動到頭的值  true 一直爲放開拖到到頭,false 慣性滑動
     */
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
//        Log.e("masai", "deltaY:" + deltaY + "    maxOverScrollY:" + maxOverScrollY + "    " + "isTouchEvent:" + isTouchEvent);
        if (deltaY < 0 && isTouchEvent) {
            //按住拖到到頭的。。動態的改變高度!!
            //--得正。。。當改變以後。必須得重新佈局一下。重新測量一下
            if (mHeaderImg != null) {
                int tempHeader = mHeaderImg.getHeight() - deltaY / 3;
                if (tempHeader < mHeaderImgMaxHeight) {
                    mHeaderImg.getLayoutParams().height = tempHeader;
                    mHeaderImg.requestLayout();
                }
            }
        }
        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
    }

    /**
     * addHeadr
     * @param i ImageView 的容器必須是 wrap_content
     */
    public void addHeader(final ImageView i) {
        this.mHeaderImg = i;
        this.mHeaderImgMaxHeight = (int) (i.getDrawable().getIntrinsicHeight() * 1.4);

        //測量出最初的高度。用於回彈
        i.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                mHeaderImgOriginalHeight = mHeaderImg.getHeight();
                i.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        });
    }


    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_UP:
                if (mHeaderImg != null) {
                    ResetAnimation resetAnimation = new ResetAnimation(mHeaderImg, mHeaderImgOriginalHeight);
                    startAnimation(resetAnimation);
                }
                break;
        }
        return super.onTouchEvent(ev);
    }


    private class ResetAnimation extends Animation {

        private View v;
        private int startHeight;
        private int endHeight;

        public ResetAnimation(View v, int endHeight) {
            super();
            this.v = v;

            this.startHeight = v.getHeight();

            this.endHeight = endHeight;

            //動畫時間
            setDuration(400);
            setInterpolator(new OvershootInterpolator());
        }

        /**
         * 會循環調用該方法,表示動畫執行的進度
         *
         * @param interpolatedTime 0 - 1!!!動畫執行的百分比,如果加了差時器的話可能到1.1,1.2
         * @param t
         */
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            super.applyTransformation(interpolatedTime, t);
//        04-19 15:38:05.226 2151-2151/? E/TAG: 457新的高度  日誌得知! 開始高度480
//        04-19 15:38:05.241 2151-2151/? E/TAG: 462新的高度
//        04-19 15:38:05.257 2151-2151/? E/TAG: 468新的高度
//        04-19 15:38:05.275 2151-2151/? E/TAG: 473新的高度
//        04-19 15:38:05.291 2151-2151/? E/TAG: 477新的高度
//        04-19 15:38:05.308 2151-2151/? E/TAG: 479新的高度
//        04-19 15:38:05.325 2151-2151/? E/TAG: 480新的高度
//        04-19 15:38:05.342 2151-2151/? E/TAG: 480新的高度
            //運動的高度!!!結束的高度-開始運動的高度。是一個-值。然後+開始的高度。。。
            int newHeader = (int) ((endHeight - startHeight) * interpolatedTime + startHeight);
            v.getLayoutParams().height = newHeader;
            v.requestLayout();
//            Log.e("TAG", newHeader + "新的高度");
        }
    }
}



我也不直接貼源代碼了。。。。差不多就是這樣了。。。。。。







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章