Android中的系统栏
16lz
2021-01-23
Android中的系统栏
话不多说,我写的上一篇 Android沉浸式状态栏 只针对 系统栏 中的 状态栏,也是最常用的,因为开发项目基本不会出现更改 导航栏 的需求,因为 导航栏 的用语与其他地方有冲突,所以我一般用 虚拟按键栏 代替,也很好理解,就是Android手机下方的三个虚拟按键,所以下面所说的更改导航可以了解一下,不排除以后公司产品告诉你需要改颜色。
获取Android4.4 - 5.0的系统栏
private static final String STATUS_BAR_TAG = "COM_BRAVE_SYSTEM_BAR_LIBRARY_STATUS_BAR";private static final String NAV_BAR_TAG = "COM_BRAVE_SYSTEM_BAR_LIBRARY_NAV_BAR";private static final View getBar(@NonNull Window window, boolean isStatusBar) { if (isAndroid_5_0_Above()) { return null; } ViewGroup decorView = (ViewGroup) window.getDecorView(); String tag = isStatusBar ? STATUS_BAR_TAG : NAV_BAR_TAG; View bar = decorView.findViewWithTag(tag); if (null == bar) { bar = new View(window.getContext()); Context context = window.getContext(); int barHeight = isStatusBar ? Utils.getStatusBarHeight(context) : Utils.getNavBarHeight(context); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, barHeight); params.gravity = Gravity.TOP; bar.setLayoutParams(params); bar.setTag(tag); decorView.addView(bar); } return bar;}private static final View getStatusBar(@NonNull Window window) { return getBar(window, true);}private static final View getNavBar(@NonNull Window window) { return getBar(window, false);}private static final boolean isAndroid_4_4_Above() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;}private static final boolean isAndroid_5_0_Above() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;}
设置Flags
private static final void setFlags(@NonNull Window window, boolean isStatusBar, boolean isNavBar, boolean isBlack, boolean preventShaking) { if (isAndroid_5_0_Above()) { window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); if (isStatusBar) { window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); } if (isNavBar) { window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); } if (preventShaking) { int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE; if (isNavBar) { option = option | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; } if (isBlack) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { option = option | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; } } else { option = option | View.SYSTEM_UI_FLAG_VISIBLE; } window.getDecorView().setSystemUiVisibility(option); } else { if (isBlack) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); } } } } else if (isAndroid_4_4_Above()) { if (isStatusBar) { window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); } if (isNavBar) { window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); } }}
设置根布局
private static final void setRootView(@NonNull View rootView, boolean fitSystemWindows, boolean clipToPadding) { if (null != rootView) { if (rootView instanceof ViewGroup) { ViewGroup viewGroup = (ViewGroup) rootView; viewGroup.setFitsSystemWindows(fitSystemWindows); viewGroup.setClipToPadding(clipToPadding); } }}
设置系统栏颜色
public static final void setSystemBarColor(@NonNull Window window, @NonNull View rootView, boolean isStatusBar, boolean isNavBar, boolean preventShaking, boolean isBlack, boolean fitSystemWindows, boolean clipToPadding, @ColorInt int color, @IntRange(from = 0, to = 255) int alpha) { if (!isStatusBar && !isNavBar) { return; } if (!isAndroid_4_4_Above()) { return; } boolean hasNavigationBar = Utils.hasNavigationBar(window); isNavBar = isNavBar && hasNavigationBar; setFlags(window, isStatusBar, isNavBar, isBlack, preventShaking); int barColor = calculateColor(color, alpha); if (isStatusBar) { if (isAndroid_5_0_Above()) { window.setStatusBarColor(barColor); } else if (isAndroid_4_4_Above()) { View statusBar = getStatusBar(window); if (statusBar.getVisibility() != View.VISIBLE) { statusBar.setVisibility(View.VISIBLE); } statusBar.setBackgroundColor(barColor); } } if (isNavBar) { if (isAndroid_5_0_Above()) { window.setNavigationBarColor(barColor); } else if (isAndroid_4_4_Above()) { View navBar = getNavBar(window); if (navBar.getVisibility() != View.VISIBLE) { navBar.setVisibility(View.VISIBLE); } navBar.setBackgroundColor(barColor); } } setRootView(rootView, fitSystemWindows, clipToPadding);}
使用
- 系统栏占位(直接给系统栏上色)
BarUtils.setSystemBarColor(getWindow(), ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0), true, true, true, true, true, true, Color.BLUE, 255);
- 设置系统栏不占位(使系统栏透明化)
BarUtils.setSystemBarColor(getWindow(), ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0), true, true, true, true, false, false, Color.BLACK, 0);
完整项目地址 SystemBarUtils
具体使用
- 半透明系统栏
BarUtils.setTranslucent(this);
- 透明系统栏
BarUtils.setTransparent(this);
- 设置系统栏颜色
BarUtils.setSystemBarColor(this, Color.BLUE);
- 设置头部ImageView
BarUtils.setSystemBarColor(this, true, false, false, false, false, Color.BLACK, 0);
- 设置抽屉布局
BarUtils.setSystemBarColor(this, true, false, false, false, false, Color.BLACK, 0);
简单说明一下,抽屉布局与头部ImageView的设置方法相同,但是需要在自己的内容布局进行一步操作,就是需要在内容布局中模拟状态栏,你直接改变你内容布局中的模拟状态栏颜色,即可实现抽屉滑动时颜色。
如果您有其他更多的需求同样可以使用该方法,只需在内容布局中就可以操作一切,当然如果您的整个APP都需要这种状态栏,你可以定义一个BaseActivity,来实现一个基布局。
更多相关文章
- android:布局参数,控件属性及各种xml的作用
- Android系统信息获取 之十二:获取屏幕分辨率及密度
- 通杀所有系统的硬件漏洞?聊一聊Drammer,Android上的RowHammer攻击
- android系统中log机制