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,来实现一个基布局。