状态栏 沉浸透明的演变

3,766 阅读1分钟

系统栏爬坑过程

代码:

//设置系统栏透明
getWindow().setStatusBarColor(Color.TRANSPARENT);
//设置全屏布局,不隐藏系统栏
view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
//设置系统栏颜色(字体反色)
WindowInsetsControllerCompat.setAppearanceLightStatusBars(true);

问题:

API29 以下布局下方出现系统状态栏大小的View 将自身布局顶上去

解决:

设置跟布局fitsSystemWindows = true
        //控制状态栏
        if (data.isStatusBar) {
//            view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
            WindowCompat.setDecorFitsSystemWindows(((AppCompatActivity) view.getContext()).getWindow(), true);
        } else {
//            view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
////                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
////                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
////                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
////                    | View.SYSTEM_UI_FLAG_IMMERSIVE
////                    | View.SYSTEM_UI_FLAG_FULLSCREEN
////                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
//            );
            WindowCompat.setDecorFitsSystemWindows(((AppCompatActivity) view.getContext()).getWindow(), false);
//            ((AppCompatActivity) view.getContext()).getWindow().setDecorFitsSystemWindows(false);
        }

新问题:

布局现在在状态栏下方,沉浸效果消失(包括API29以上)

解决: 不断尝试过程中发现一个兼容的神奇方法

WindowCompat.setDecorFitsSystemWindows(((AppCompatActivity) view.getContext()).getWindow(), isShow);

文档:

Sets whether the decor view should fit root-level content views for WindowInsetsCompat. If set to false, the framework will not fit the content view to the insets and will just pass through the WindowInsetsCompat to the content view.

google翻译的一塌糊涂,我理解上面这段话的意思是说是否设置将系统栏这些系统View塞进ContentView中,如果设置为false,框架将无法将系统栏等系统View塞进ContentView,而是通过WindowInsetsCompat填充到ContentView,不知道我理解的对不对,看了下API30以下的实现方式,其实就是设置了View.setSystemUiVisibility View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;这跟我在尝试解决上面问题时尝试的方式一样。

参考文献

developer.android.google.cn/training/sy…

补充:

API25 又出现了布局下方出现系统状态栏大小的View 将自身布局顶上去的问题

探索:

布局下方出现系统状态栏大小的View 将自身布局顶上去

View.requestFitSystemWindows()

该方法解决所有版本的问题,在研究吧

最终夸版本的状态栏沉浸可由以下代码实现

        //设置系统栏透明
        getWindow().setStatusBarColor(Color.TRANSPARENT);
        //控制状态栏
        WindowCompat.setDecorFitsSystemWindows(((AppCompatActivity) view.getContext()).getWindow(),
                data.isStatusBar);
        //view.requestFitSystemWindows(); 替换为以下
        ViewCompat.requestApplyInsets(window.getDecorView());
        
        WindowInsetsControllerCompat controller = ViewCompat.getWindowInsetsController(view);
        if (controller != null) {
            //状态栏颜色
            controller.setAppearanceLightStatusBars(data.statusBarWhite);
        }