1. 程式人生 > >漫談透明狀態列和沉浸式狀態列

漫談透明狀態列和沉浸式狀態列

package com.example.administrator.mystatusbar;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import java.lang.reflect.Field;

public class ImmersiveHelper {
    private Context mContext;
    private int mAlpha;
    private View mStatusBar;
    private View mContentView;
    private ObservableScrollView mScrollView;
    private int mStatusHeight;
    private int mTotalHeight;
    private boolean isImmersived;
    private ObservableScrollView.ScrollViewListener listener;

    public ImmersiveHelper(Context mContext, View mStatusBar, final View mContentView, ObservableScrollView mScrollView) {
        this.mContext = mContext;
        this.mStatusBar = mStatusBar;
        this.mContentView = mContentView;
        this.mScrollView = mScrollView;
    }

    public void init(final Runnable runnable){
        mStatusHeight = setStatusViewHeight(mContext,mStatusBar);
        mContentView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                if (mContentView.getMeasuredHeight() != 0){
                    mTotalHeight = mStatusHeight + mContentView.getMeasuredHeight();
                    runnable.run();
                }
                mContentView.getViewTreeObserver().removeOnPreDrawListener(this);
                return false;
            }
        });
    }

    public void onRestoreData(Bundle bundle){
        mTotalHeight = bundle.getInt("totalHeight");
    }

    public void onSaveData(Bundle bundle){
        bundle.putInt("totalHeight",mTotalHeight);
    }

    public boolean isImmersived() {
        return isImmersived;
    }

    public int getTotalHeight() {
        return  mTotalHeight;
    }

    /**
     * 設定當前沉浸的狀態
     */
    public void setImmversive(boolean isOpen, final Runnable runnable){
        if(isOpen){
            if(!isImmersived) {
                mContentView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                    @Override
                    public boolean onPreDraw() {
                        int immerseHeight = mContext.getResources().getDisplayMetrics().widthPixels / 2 - mContentView.getMeasuredHeight() - mStatusHeight;
                        listener = setImmersiveEnabled(mScrollView, mStatusBar, mContentView, immerseHeight);
                        logD("setImmersive-->true");
                        isImmersived = true;
                        if(null != runnable){
                            runnable.run();
                        }
                        mScrollView.scrollTo(0,0);
                        mScrollView.invalidate();
                        mContentView.getViewTreeObserver().removeOnPreDrawListener(this);
                        return false;
                    }
                });
            }
        }else if(isImmersived){
            mScrollView.scrollTo(0,0);
            mScrollView.invalidate();
            mScrollView.removeScrollViewListener(listener);
            mAlpha = 255;
            mStatusBar.getBackground().mutate().setAlpha(mAlpha);
            mContentView.getBackground().mutate().setAlpha(mAlpha);
            logD("setImmersive-->false");
            isImmersived = false;
            if(null != runnable){
                runnable.run();
            }
        }
    }

    /**
     * 設定沉浸式互動
     * @param height 沉浸的總高度
     */
    public ObservableScrollView.ScrollViewListener setImmersiveEnabled(ObservableScrollView scrollView, final View status, final View content, final int height){
        mAlpha = 0;
        content.getBackground().mutate().setAlpha(mAlpha);
        status.getBackground().mutate().setAlpha(mAlpha);
        ObservableScrollView.ScrollViewListener listener = new ObservableScrollView.ScrollViewListener() {
            @Override
            public void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy) {
                int alpha = Math.max(0,Math.min(255,(int) (255 * (scrollView.getScrollY()) * 1.0f / height)));
                if(mAlpha != alpha) {
                    content.getBackground().mutate().setAlpha(alpha);
                    status.getBackground().mutate().setAlpha(alpha);
                    mAlpha = alpha;
                }
            }
        };
        scrollView.addScrollViewListener(listener);
        return listener;
    }

    private void logD(String text){
        Log.d("ImmersiveHelper", text);
    }

    /**
     * 設定需要充當狀態列的檢視高度
     * @param viewStatus 檢視
     */
    public static int setStatusViewHeight(Context mContext,View viewStatus){
        int statusHeight = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT?getStatusBarHeight(mContext):0;
        ViewGroup.LayoutParams params = viewStatus.getLayoutParams();
        if(statusHeight != params.height) {
            params.height = statusHeight;
            viewStatus.requestLayout();
        }
        return statusHeight;
    }

    /**
     * 獲取狀態列高度
     *
     * @param context
     * @return
     */
    public static int getStatusBarHeight(Context context) {
        /*Rect rect = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        return rect.top;*/

        try {
            Class c = Class.forName("com.android.internal.R$dimen");
            Object obj = c.newInstance();
            Field field = c.getField("status_bar_height");
            int x = Integer.parseInt(field.get(obj).toString());
            int y = context.getResources().getDimensionPixelSize(x);
            return y;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }


}