• 沉浸式状态栏工具类


    package com.loaderman.samplecollect.immersion_status_bar;
    
    import android.app.Activity;
    import android.content.Context;
    import android.graphics.Color;
    import android.graphics.drawable.Drawable;
    import android.os.Build;
    import android.support.v4.widget.DrawerLayout;
    import android.support.v7.app.ActionBar;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.util.TypedValue;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.LinearLayout;
    
    
    
    public class StatusBarUtils {
        private Activity mActivity;
        //状态栏颜色
        private int mColor = -1;
        //状态栏drawble
        private Drawable mDrawable;
        //是否是最外层布局是 DrawerLayout 的侧滑菜单
        private boolean mIsDrawerLayout;
        //是否包含 ActionBar
        private boolean mIsActionBar;
        //侧滑菜单页面的内容视图
        private int mContentResourseIdInDrawer;
    
        public StatusBarUtils(Activity activity) {
            mActivity = activity;
        }
    
        public static StatusBarUtils with(Activity activity) {
            return new StatusBarUtils(activity);
        }
    
        public int getColor() {
            return mColor;
        }
    
        public StatusBarUtils setColor(int color) {
            mColor = color;
            return this;
        }
    
        public Drawable getDrawable() {
            return mDrawable;
        }
    
        public StatusBarUtils setDrawable(Drawable drawable) {
            mDrawable = drawable;
            return this;
        }
    
        public boolean isDrawerLayout() {
            return mIsDrawerLayout;
        }
    
        public boolean isActionBar() {
            return mIsActionBar;
        }
    
        public StatusBarUtils setIsActionBar(boolean actionBar) {
            mIsActionBar = actionBar;
            return this;
        }
    
        /**
         * 是否是最外层布局为 DrawerLayout 的侧滑菜单
         *
         * @param drawerLayout 是否最外层布局为 DrawerLayout
         * @param contentId    内容视图的 id
         * @return
         */
        public StatusBarUtils setDrawerLayoutContentId(boolean drawerLayout, int contentId) {
            mIsDrawerLayout = drawerLayout;
            mContentResourseIdInDrawer = contentId;
            return this;
        }
    
        public void init() {
            fullScreen(mActivity);
            if (mColor != -1) {
                //设置了状态栏颜色
                addStatusViewWithColor(mActivity, mColor);
            }
            if (mDrawable != null) {
                //设置了状态栏 drawble,例如渐变色
                addStatusViewWithDrawble(mActivity, mDrawable);
            }
            if (isDrawerLayout()) {
                //未设置 fitsSystemWindows 且是侧滑菜单,需要设置 fitsSystemWindows 以解决 4.4 上侧滑菜单上方白条问题
                fitsSystemWindows(mActivity);
            }
            if (isActionBar()) {
                //要增加内容视图的 paddingTop,否则内容被 ActionBar 遮盖
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    ViewGroup rootView = (ViewGroup) mActivity.getWindow().getDecorView().findViewById(android.R.id.content);
                    rootView.setPadding(0, getStatusBarHeight(mActivity) + getActionBarHeight(mActivity), 0, 0);
                }
            }
        }
    
        /**
         * 去除 ActionBar 阴影
         */
        public StatusBarUtils clearActionBarShadow() {
            if (Build.VERSION.SDK_INT >= 21) {
                ActionBar supportActionBar = ((AppCompatActivity) mActivity).getSupportActionBar();
                if (supportActionBar != null) {
                    supportActionBar.setElevation(0);
                }
            }
            return this;
        }
    
        /**
         * 设置页面最外层布局 FitsSystemWindows 属性
         *
         * @param activity
         */
        private void fitsSystemWindows(Activity activity) {
            ViewGroup contentFrameLayout = (ViewGroup) activity.findViewById(android.R.id.content);
            View parentView = contentFrameLayout.getChildAt(0);
            if (parentView != null && Build.VERSION.SDK_INT >= 14) {
                parentView.setFitsSystemWindows(true);
                //布局预留状态栏高度的 padding
                if (parentView instanceof DrawerLayout) {
                    DrawerLayout drawer = (DrawerLayout) parentView;
                    //将主页面顶部延伸至status bar;虽默认为false,但经测试,DrawerLayout需显示设置
                    drawer.setClipToPadding(false);
                }
            }
        }
    
        /**
         * 利用反射获取状态栏高度
         *
         * @return
         */
        public static int getStatusBarHeight(Activity activity) {
            int result = 0;
            //获取状态栏高度的资源id
            int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
            if (resourceId > 0) {
                result = activity.getResources().getDimensionPixelSize(resourceId);
            }
            Log.e("getStatusBarHeight", result + "");
            return result;
        }
    
        /**
         * 获得 ActionBar 的高度
         *
         * @param context
         * @return
         */
        public static int getActionBarHeight(Context context) {
            int result = 0;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                TypedValue tv = new TypedValue();
                context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true);
                result = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
            }
            return result;
        }
    
        /**
         * 添加状态栏占位视图
         *
         * @param activity
         */
        private void addStatusViewWithColor(Activity activity, int color) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                if (isDrawerLayout()) {
                    //要在内容布局增加状态栏,否则会盖在侧滑菜单上
                    ViewGroup rootView = (ViewGroup) activity.findViewById(android.R.id.content);
                    //DrawerLayout 则需要在第一个子视图即内容试图中添加padding
                    View parentView = rootView.getChildAt(0);
                    LinearLayout linearLayout = new LinearLayout(activity);
                    linearLayout.setOrientation(LinearLayout.VERTICAL);
                    View statusBarView = new View(activity);
                    ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                            getStatusBarHeight(activity));
                    statusBarView.setBackgroundColor(color);
                    //添加占位状态栏到线性布局中
                    linearLayout.addView(statusBarView, lp);
                    //侧滑菜单
                    DrawerLayout drawer = (DrawerLayout) parentView;
                    //内容视图
                    View content = activity.findViewById(mContentResourseIdInDrawer);
                    //将内容视图从 DrawerLayout 中移除
                    drawer.removeView(content);
                    //添加内容视图
                    linearLayout.addView(content, content.getLayoutParams());
                    //将带有占位状态栏的新的内容视图设置给 DrawerLayout
                    drawer.addView(linearLayout, 0);
                } else {
                    //设置 paddingTop
                    ViewGroup rootView = (ViewGroup) mActivity.getWindow().getDecorView().findViewById(android.R.id.content);
                    rootView.setPadding(0, getStatusBarHeight(mActivity), 0, 0);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        //直接设置状态栏颜色
                        activity.getWindow().setStatusBarColor(color);
                    } else {
                        //增加占位状态栏
                        ViewGroup decorView = (ViewGroup) mActivity.getWindow().getDecorView();
                        View statusBarView = new View(activity);
                        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                                getStatusBarHeight(activity));
                        statusBarView.setBackgroundColor(color);
                        decorView.addView(statusBarView, lp);
                    }
                }
            }
        }
    
        /**
         * 添加状态栏占位视图
         *
         * @param activity
         */
        private void addStatusViewWithDrawble(Activity activity, Drawable drawable) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                //占位状态栏
                View statusBarView = new View(activity);
                ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                        getStatusBarHeight(activity));
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    statusBarView.setBackground(drawable);
                } else {
                    statusBarView.setBackgroundDrawable(drawable);
                }
                if (isDrawerLayout()) {
                    //要在内容布局增加状态栏,否则会盖在侧滑菜单上
                    ViewGroup rootView = (ViewGroup) activity.findViewById(android.R.id.content);
                    //DrawerLayout 则需要在第一个子视图即内容试图中添加padding
                    View parentView = rootView.getChildAt(0);
                    LinearLayout linearLayout = new LinearLayout(activity);
                    linearLayout.setOrientation(LinearLayout.VERTICAL);
                    //添加占位状态栏到线性布局中
                    linearLayout.addView(statusBarView, lp);
                    //侧滑菜单
                    DrawerLayout drawer = (DrawerLayout) parentView;
                    //内容视图
                    View content = activity.findViewById(mContentResourseIdInDrawer);
                    //将内容视图从 DrawerLayout 中移除
                    drawer.removeView(content);
                    //添加内容视图
                    linearLayout.addView(content, content.getLayoutParams());
                    //将带有占位状态栏的新的内容视图设置给 DrawerLayout
                    drawer.addView(linearLayout, 0);
                } else {
                    //增加占位状态栏,并增加状态栏高度的 paddingTop
                    ViewGroup decorView = (ViewGroup) mActivity.getWindow().getDecorView();
                    decorView.addView(statusBarView, lp);
                    //设置 paddingTop
                    ViewGroup rootView = (ViewGroup) mActivity.getWindow().getDecorView().findViewById(android.R.id.content);
                    rootView.setPadding(0, getStatusBarHeight(mActivity), 0, 0);
                }
            }
        }
    
        /**
         * 通过设置全屏,设置状态栏透明
         *
         * @param activity
         */
        private void fullScreen(Activity activity) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    //5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色
                    Window window = activity.getWindow();
                    View decorView = window.getDecorView();
                    //两个 flag 要结合使用,表示让应用的主体内容占用系统状态栏的空间
                    int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
                    window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                    decorView.setSystemUiVisibility(option);
                    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                    window.setStatusBarColor(Color.TRANSPARENT);
                    //导航栏颜色也可以正常设置
    //                window.setNavigationBarColor(Color.TRANSPARENT);
                } else {
                    Window window = activity.getWindow();
                    WindowManager.LayoutParams attributes = window.getAttributes();
                    int flagTranslucentStatus = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
                    int flagTranslucentNavigation = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
                    attributes.flags |= flagTranslucentStatus;
    //                attributes.flags |= flagTranslucentNavigation;
                    window.setAttributes(attributes);
                }
            }
        }
    
        /**
         * 通过设置全屏,设置状态栏透明 导航栏黑色
         *
         * @param activity
         */
        public static void setStatusTransparent(Activity activity) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    Window window = activity.getWindow();
    
                    WindowManager.LayoutParams attributes = window.getAttributes();
                    int flagTranslucentStatus = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
                    int flagTranslucentNavigation = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
    //                attributes.flags |= flagTranslucentStatus;
                    attributes.flags |= flagTranslucentNavigation;
                    window.setAttributes(attributes);
    
                    window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
                    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                    window.setStatusBarColor(Color.TRANSPARENT);
                    window.setNavigationBarColor(Color.TRANSPARENT);
                } else {
                    Window window = activity.getWindow();
                    WindowManager.LayoutParams attributes = window.getAttributes();
                    int flagTranslucentStatus = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
                    int flagTranslucentNavigation = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
                    attributes.flags |= flagTranslucentStatus;
                    attributes.flags |= flagTranslucentNavigation;
                    window.setAttributes(attributes);
                }
            }
        }
    }

    使用

    渐变状态栏

      StatusBarUtils.with(this)
                    .setIsActionBar(true)
                    .clearActionBarShadow()
                    .setDrawable(getResources().getDrawable(R.drawable.shape))
                    .init();

    常规一色状态栏

            StatusBarUtils.with(this)
                    .setColor(getResources().getColor(R.color.blue))
    //                .setDrawable(getResources().getDrawable(R.drawable.shape))
                    .init();
    沉浸式图片 , 头布局是图片布局
         StatusBarUtils.with(this)
                    .init(); 

    侧滑常规显示页面

        StatusBarUtils.with(this)
                    .setDrawerLayoutContentId(true, R.id.rl_content)
                    .setColor(getResources().getColor(R.color.blue))
                    .init();

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
    
        <gradient
            android:angle="0"
            android:centerX="0.7"
            android:endColor="@color/shape2"
            android:startColor="@color/shape1"
            android:centerColor="@color/shape3"
            android:type="linear" />
    </shape>

    效果图:

  • 相关阅读:
    FreeRTOS——队列管理
    Replication Controller、Replica Set
    基本概念与组件
    YAML配置文件
    curl命令测试服务器是否支持断点续传
    浏览器http跳转至https问题
    常用Linux日志文件功能
    SSH连接时,长时间不操作就断开的解觉办法
    防HTTP慢速攻击的nginx安全配置
    Centos6.5升级安装openssh7.7p1
  • 原文地址:https://www.cnblogs.com/loaderman/p/10172642.html
Copyright © 2020-2023  润新知