前言
我们经常可以在App中看到这样一种效果:
可以看到,状态栏与App自身的标题栏融合在了一块,相比于原生黑色的状态栏,给用户的整体视觉效果更佳,那么如何实现Android状态栏一体化效果?
实现
在你所要实现沉浸的页面的Activity中添加如下代码:
//判断当前设备版本号是否为4.4以上,如果是,则通过调用setTranslucentStatus让状态栏变透明
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
setTranslucentStatus(true);
}
@TargetApi(19)
private void setTranslucentStatus(boolean on) {
Window win = getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
if (on) {
winParams.flags |= bits;
} else {
winParams.flags &= ~bits;
}
win.setAttributes(winParams);
}
这里定义的setTranslucentStatus方法能够设置系统状态栏为透明,并且系统会取消状态栏原本所占的空间,普通布局会上移并占用状态栏所在位置的空间
此时运行效果如下:
但是看起来不是我们想要的效果,正常应该是标题栏不占用状态栏的空间,并且要使状态栏颜色与我们的标题栏一致。
解决思路:在页面顶部加上一个普通的View,设置该View的高度与当前设备的状态栏的高度一致,再给这个View设置上与标题栏一样的颜色。
首先在activity布局文件中加入一个用来腾出状态栏空间的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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.zjyang.statubardemo.MainActivity">
<!--此View用来腾出状态栏的空间,设置颜色与标题栏一致-->
<View
android:id="@+id/paddingView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#32A082"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"
android:background="#32A082">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="#fff"
android:text="首页"/>
</LinearLayout>
</LinearLayout>
在Activity中再加入如下代码:
1.获取当前设备状态栏高度
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
2.获取顶部View,动态设置高度
View paddingView = findViewById(R.id.paddingView);
ViewGroup.LayoutParams params = paddingView.getLayoutParams();
params.height = getStatusBarHeight();
运行效果:
可以看到,标题栏回到了原本的位置,状态栏也融为了一体,实现了我们想要的效果。
上面实现了纯颜色标题栏的情况下一体化,下面再尝试用背景图片与状态栏一体化的效果:
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.zjyang.statubardemo.MainActivity">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg"/>
</LinearLayout>
这里我随便加上一张背景图,至于之前的那个作为腾出空间的View就不再需要了(包括上面提到的获取状态栏高度以及动态设置PadddingView的高度都不需要了),因为背景图片本身直接顶上去状态栏才能看起来一体化。
再次运行:
附上整体代码:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//判断当前设备版本号是否为4.4以上,如果是,则通过调用setTranslucentStatus让状态栏变透明
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
setTranslucentStatus(true);
}
/**如果是纯色标题栏的情况,需要动态设置paddingView的高度**/
// View paddingView = findViewById(R.id.paddingView);
// ViewGroup.LayoutParams params = paddingView.getLayoutParams();
// params.height = getStatusBarHeight();
}
/**
* 获取当前设备状态栏高度
* @return
*/
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
/**
* 设置状态栏透明
* @param on
*/
@TargetApi(19)
private void setTranslucentStatus(boolean on) {
Window win = getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
if (on) {
winParams.flags |= bits;
} else {
winParams.flags &= ~bits;
}
win.setAttributes(winParams);
}
}
当然,实现这种效果的思路可能不止这一种,如果有其他更好的方式欢迎讨论。