Android真正的沉浸式状态栏
之前也看了很多关于沉浸式状态栏的文章,但大部分都不尽人意,要么是功能没有完全实现,要么是代码写的你看不懂,后来在掘金上看到了一篇文章写的比较好,再结合自己的理解做了一下完善,先记下来以后会用得到的。
Android在4.4d的版本之后,推出了沉浸式状态栏,允许通过第三方软件来更改状态栏的颜色,让整个面完全与App的风格融为一体。效果如下图所示
这两张图,一张状态栏是用图片填充的,另一张状态栏则是单一的颜色,好了话不多说,我们直接来看怎么实现的。我们先来实现第一张图的效果。
首先我们要把系统原先的状态栏变透明,这个处理操作在4.4版本和5.0之上的版本是不一样的,必须分开处理,不然可能得不到你想要的结果,即状态栏上面会有一层暗灰的视图,看起来非常不爽。
4.4-5.0版本的处理方法:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
5.0之上的处理方法:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
Window window = getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
window.setStatusBarColor(Color.TRANSPARENT);
}
下面是该布局文件的代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.zaozao.hu.MainActivity">
<ImageView
android:src="@mipmap/pic2"
android:scaleType="fitXY"
android:layout_width="match_parent"
android:layout_height="200dp" />
<TextView
android:background="@android:color/holo_red_dark"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="沉浸式状态栏的实现" />
</LinearLayout>
这样就可以了吗?是的这样第一副图片的功能我们就实现了,不要加上fitSystemWindow这个属性
接下来,我们来实现第二幅图,第二幅图和第一幅图的区别在于它的状态栏是纯色的,所以实现起来略有不同,
如果我们继续用第一种方法来实现的话,那么得到结果将是这样的
和第二张图有什么区别,大家应该一眼就看出来了,我在布局文件里面将上面标题的高度设置的49dp,没错你现在看到的也是49dp
但你肯定发现哪里不对了,是的状态栏的高度不见了,而是把整个布局向上移动了,导致状态栏和标题栏重叠了,那么怎么解决这个问题
呢?有两种方法:
一、将布局文件的根标签的背景设置成标题栏相同的颜色,然后再加上android:fitSystemWindows="true"这个属性
这样状态栏就会去找设置了这个属性的标签,然后将这个标签的背景色设置为状态栏自己的颜色。(如下)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true"
android:background="@android:color/holo_green_dark"
tools:context="com.zaozao.hu.MainActivity">
二、动态添加一个view,将它的高度设置为状态栏的高度,颜色设置标题栏的颜色,这样来弥补原来状态栏的位置。布局文件如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.zaozao.hu.MainActivity">
<LinearLayout
android:id="@+id/ll_bar"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/holo_green_dark"
android:orientation="vertical"
android:visibility="gone" />
<TextView
android:layout_width="match_parent"
android:layout_height="49dp"
android:background="@android:color/holo_green_dark"
android:gravity="center"
android:text="我的沉浸式状态栏"
android:textColor="@android:color/black" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_red_dark"
android:gravity="center"
android:text="沉浸式状态栏的实现" />
</LinearLayout>
核心代码:
private void initStatus() {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
Window window = getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
window.setStatusBarColor(Color.TRANSPARENT);
}else{
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.ll_bar);
linearLayout.setVisibility(View.VISIBLE);
int statusBarHeight = getStatusBarHeight();
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) linearLayout.getLayoutParams();
params.height = statusBarHeight;
linearLayout.setLayoutParams(params);
}
}
/**
* 通过反射获取状态栏的高度
* @return
*/
private int getStatusBarHeight() {
try {
Class<?> c = Class.forName("com.android.internal.R$dimen");
Object obj = c.newInstance();
Field field = c.getField("status_bar_height");
int x = Integer.parseInt(field.get(obj).toString());
return getResources().getDimensionPixelSize(x);
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
到此为止,大功告成,如有代码看不懂的地方,请自行百度。