手动给根视图设置一个 paddingTop ,高度为状态栏高度,相当于手动实现了 fitsSystemWindows=true 的效果,然后再在根视图加入一个占位视图,其高度也设置为状态栏高度。
//设置 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) { //5.0 以上直接设置状态栏颜色 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); }个人认为最优解应该是第三种方法,通过这种方法达到沉浸式的效果后面也可以很方便地拓展出渐变色的状态栏。
方法二:代码中设置通过在代码中设置,实现方法一中在 Theme 主题样式里设置的属性,便于封装。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { int flagTranslucentStatus = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; int flagTranslucentNavigation = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Window window = getWindow(); WindowManager.LayoutParams attributes = window.getAttributes(); attributes.flags |= flagTranslucentNavigation; window.setAttributes(attributes); getWindow().setStatusBarColor(Color.TRANSPARENT); } else { Window window = getWindow(); WindowManager.LayoutParams attributes = window.getAttributes(); attributes.flags |= flagTranslucentStatus | flagTranslucentNavigation; window.setAttributes(attributes); } }但是从图片中也看到了,该方案会导致一个问题就是导航栏颜色变灰。
经测试,在 5.x 以下导航栏透明是可以生效的,但 5.x 以上导航栏会变灰色(正常情况下我们期望导航栏保持默认颜色黑色不变),但因为设置了FLAG_TRANSLUCENT_NAVIGATION,所以即使代码中设置 getWindow().setNavigationBarColor(Color.BLACK); 也是不起作用的。但如果不设置该 FLAG ,状态栏又无法被置为隐藏和设置透明。
通过设置 FLAG ,让应用内容占用系统状态栏的空间,经测试该方式不会影响对导航栏的设置。
/** * 通过设置全屏,设置状态栏透明 * * @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; 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); } } } 验证其他使用场景 侧滑菜单使用 AS 自动创建 Navigation Drawer Activity ,布局结构为:
DrawerLayout
include :内容布局,默认使用 ToolBar
NavigationView :侧滑布局
这里只调用了 fullScreen(), 测试一下运行结果如何: