Android沉浸式状态栏
沉浸式状态栏,就我所使用的一共两种类型
- 状态栏不占位
- 状态栏占位
解释什么是状态栏不占位与状态栏占位之前,我们先把一个Activity页面理解成,Activity布局由两部分组成:根布局 + 内容布局。
根布局 : 就是Android系统已经完成的布局,如我们所看到的顶部的状态栏与底部的虚拟按键栏(这个有些手机上没有)。
内容布局 : 就是我们layout文件下创建的布局,也就是在Activity中调用setContentView(R.layout.activity_xxx);方法中的activity_xxx。
状态栏不占位
个人理解 : 就是状态栏需要显示,但是不具备占位功能,而是像相对布局一样,悬浮在内容布局的上方,按照这个理解,就能很容易的实现,传说中的沉浸式状态栏了。
实现两点: 状态栏透明 + 状态栏不占位
// Android 4.4+
private static final boolean isAndroid_4_4_Above() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
}
// Android 5.0+
private static final boolean isAndroid_5_0_Above() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
}
// 清除标记
private static final void setFlags(@NonNull Window window) {
if (isAndroid_5_0_Above()) {
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
} else if (isAndroid_4_4_Above()) {
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
// android4.4 + 获取状态
private static final View getStatusBar(@NonNull Window window) {
if (isAndroid_5_0_Above()) {
return null;
}
ViewGroup decorView = (ViewGroup) window.getDecorView();
View bar = decorView.findViewWithTag(STATUS_BAR_TAG);
if (null == bar) {
bar = new View(window.getContext());
Context context = window.getContext();
int barHeight = Utils.getStatusBarHeight(context);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT, barHeight);
params.gravity = Gravity.TOP;
bar.setLayoutParams(params);
bar.setTag(STATUS_BAR_TAG);
decorView.addView(bar);
}
return bar;
}
// 设置根布局参数
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);
}
}
}
// 更改状态栏颜色透明
setFlags(window);
if (isAndroid_5_0_Above()) {
window.setStatusBarColor(Color.TRANSPARENT);
} else if (isAndroid_4_4_Above()) {
View statusBar = getStatusBar(window);
statusBar.setBackgroundColor(Color.TRANSPARENT);
}
// 设置状态栏不占位
setRootView(activity.findViewById(android.R.id.content).getChildAt(0), false, false);
按照上述步奏即可实现状态栏透明与不占位,完整代码请查看BarUtils
例子:小米手机的天气APP,在顶部状态栏需要显示动图,所以靠状态栏占位,设置状态栏颜色,这一方法是不能搞定的
状态栏占位
话不多说,直接上代码
// 更改状态栏颜色
setFlags(window);
if (isAndroid_5_0_Above()) {
window.setStatusBarColor(color);
} else if (isAndroid_4_4_Above()) {
View statusBar = getStatusBar(window);
statusBar.setBackgroundColor(color);
}
// 设置状态栏占位
setRootView(activity.findViewById(android.R.id.content).getChildAt(0), true, true);
步奏与状态栏不占位相同,知识最后调用传值有变化而已,完整代码请查看BarUtils
例子:其实也没什么好举例的,因为最经典的就是大家都知道 微信 了
快捷实现
一般,如果项目只要求显示状态栏,我会使用StatusBarUtil库。
他这里对状态栏的归类比较齐全,基本不需要自己进行其他操作。
直接上步奏:
implementation 'com.jaeger.statusbarutil:library:1.5.1'
使用:这里我就不多说了他的库里有写使用说明,我直接给个超链接吧