美文网首页
Android--SDK4.4-5.0的沉浸式状态栏适配

Android--SDK4.4-5.0的沉浸式状态栏适配

作者: aruba | 来源:发表于2020-03-19 10:35 被阅读0次
    1 .FitsSystemWindows和ClipToPadding联合运用
    我们找到DecroView中的id为content的Framelayout,添加一个高度为statusBar高度的控件,然后调用下面方法
        /**
         * 设置根布局参数
         */
        private static void setRootView(Activity activity) {
            ViewGroup parent = (ViewGroup) activity.findViewById(android.R.id.content);
            for (int i = 0, count = parent.getChildCount(); i < count; i++) {
                View childView = parent.getChildAt(i);
                if (childView instanceof ViewGroup) {
                    //调用此方法系统会默认设置paddingTop,由于调用此方法之前add了一个paddingTop高度的view用于沉浸式状态栏
                    childView.setFitsSystemWindows(true);
                    //不影响滑动效果(如ListView)(滑动区还是整个view,不设置会缺少上面的paddingTop)
                    ((ViewGroup) childView).setClipToPadding(true);
                }
            }
        }
    
    2.在普通布局文件中添加一个View,在代码中动态改变高度,把它变成statusBar高度,不需要设置FitsSystemWindows,这种方法侵入性更高,不推荐使用
    方法1中的完整方法如下:
        private static final int FAKE_STATUS_BAR_VIEW_ID = R.id.statusbarutil_fake_status_bar_view;
    
        /**
         * 设置状态栏颜色
         *
         * @param activity       需要设置的activity
         * @param color          状态栏颜色值
         * @param statusBarAlpha 状态栏透明度
         */
    
        public static void setColor(Activity activity, @ColorInt int color, @IntRange(from = 0, to = 255) int statusBarAlpha) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                activity.getWindow().setStatusBarColor(calculateStatusColor(color, statusBarAlpha));
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
                View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
                if (fakeStatusBarView != null) {
                    if (fakeStatusBarView.getVisibility() == View.GONE) {
                        fakeStatusBarView.setVisibility(View.VISIBLE);
                    }
                    fakeStatusBarView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
                } else {
                    decorView.addView(createStatusBarView(activity, color, statusBarAlpha));
                }
                setRootView(activity);
            }
        }
    
        /**
         * 计算状态栏颜色
         *
         * @param color color值
         * @param alpha alpha值
         * @return 最终的状态栏颜色
         */
        private static int calculateStatusColor(@ColorInt int color, int alpha) {
            if (alpha == 0) {
                return color;
            }
            float a = 1 - alpha / 255f;
            int red = color >> 16 & 0xff;
            int green = color >> 8 & 0xff;
            int blue = color & 0xff;
            red = (int) (red * a + 0.5);
            green = (int) (green * a + 0.5);
            blue = (int) (blue * a + 0.5);
            return 0xff << 24 | red << 16 | green << 8 | blue;
        }
    
        /**
         * 设置根布局参数
         */
        private static void setRootView(Activity activity) {
            ViewGroup parent = (ViewGroup) activity.findViewById(android.R.id.content);
            for (int i = 0, count = parent.getChildCount(); i < count; i++) {
                View childView = parent.getChildAt(i);
                if (childView instanceof ViewGroup) {
                    //调用此方法系统会默认设置paddingTop,由于调用此方法之前add了一个paddingTop高度的view用于沉浸式状态栏
                    childView.setFitsSystemWindows(true);
                    //不影响滑动效果(如ListView)(滑动区还是整个view,不设置会缺少上面的paddingTop)
                    ((ViewGroup) childView).setClipToPadding(true);
                }
            }
        }
    
        /**
         * 生成一个和状态栏大小相同的半透明矩形条
         *
         * @param activity 需要设置的activity
         * @param color    状态栏颜色值
         * @param alpha    透明值
         * @return 状态栏矩形条
         */
        private static View createStatusBarView(Activity activity, @ColorInt int color, int alpha) {
            // 绘制一个和状态栏一样高的矩形
            View statusBarView = new View(activity);
            LinearLayout.LayoutParams params =
                new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));
            statusBarView.setLayoutParams(params);
            statusBarView.setBackgroundColor(calculateStatusColor(color, alpha));
            statusBarView.setId(FAKE_STATUS_BAR_VIEW_ID);
            return statusBarView;
        }
    
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <item type="id" name="statusbarutil_fake_status_bar_view" />
        <item type="id" name="statusbarutil_translucent_view" />
    </resources>
    
    另外,如果我们想要修改状态栏的字体颜色和图标颜色,需要安卓6.0以上版本或者小米和魅族等部分厂商可以修改,6.0可以在主题中设置
    <item name="android:windowLightStatusBar">true</item>
    
    只有两种模式,true字体是深色和false是浅色

    相关文章

      网友评论

          本文标题:Android--SDK4.4-5.0的沉浸式状态栏适配

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