美文网首页
Android沉浸式状态栏/状态栏设置背景图片/自定义渐变式状态

Android沉浸式状态栏/状态栏设置背景图片/自定义渐变式状态

作者: 苏坡坡要吃婆婆酥 | 来源:发表于2019-06-14 17:40 被阅读0次

    先图为敬。

    1.普通效果

    普通效果.jpg

    2.状态栏为背景图片效果

    状态栏为图片效果.jpg

    3.侧滑页面效果

    侧滑页面效果.jpg

    4.自定义渐变效果

    自定义渐变效果.jpg

    5.含ActionBar效果

    含ActionBar效果.jpg

    工具类

    package 包名;
    
    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);
                }
            }
        }
    }
    

    用法

    1.普通效果

     //清单文件中要设置主题为NoActionBar
     StatusBarUtils.with(this)
                    .setColor(getResources().getColor(R.color.blue))
                    .init();
    

    2.图片背景效果

     //清单文件中要设置主题为NoActionBar
    //在布局文件中设置的第一个view的背景图片则为当前状态栏背景图片
     StatusBarUtils.with(this)
                    .init();
    

    3.侧滑页面状态栏效果

     //清单文件中要设置主题为NoActionBar
    //R.id.rl_content为主页面布局
    //代码中设置的为主页面状态栏
    //在侧滑页面布局文件中设置的第一个view的背景图片则为侧滑状态栏背景图片
          StatusBarUtils.with(this)
                    .setDrawerLayoutContentId(true, R.id.rl_content)
                    .setColor(getResources().getColor(R.color.blue))
                    .init();
    

    4.自定义渐变状态栏

     //当前案例含ActionBar
        StatusBarUtils.with(this)
                    .setIsActionBar(true)
                    .clearActionBarShadow()
                    .setDrawable(getResources().getDrawable(R.drawable.shape))
                    .init();
    

    自定义渐变shape

    <?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>
    

    相关文章

      网友评论

          本文标题:Android沉浸式状态栏/状态栏设置背景图片/自定义渐变式状态

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