android实现沉浸式状态栏有很多种方式,这里介绍常见的几种
1、 第一种方法:使用开源库:https://github.com/jgilfelt/SystemBarTint
2、 第二种方法:改变style属性:
如果想让整个应用状态栏同步,即改变manifest中application的style
android:theme="@style/AppTheme"
在AppTheme中修改以下两个属性
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
其中colorPrimary 代表ActionBar的颜色,colorPrimaryDark代表状态栏的颜色
如果只想单个activity实现这样的效果,那么只需要让activity的style继承Application的style即可。
<style name="ActTheme"parent="AppTheme">
<!-- Customize your theme here.-->
<itemname="colorPrimary">@color/title</item>
<itemname="colorPrimaryDark">@color/colorPrimaryDark</item>
<itemname="colorAccent">@color/colorAccent</item>
</style>
目前只在androidN上测试过,关于低版本的机子还未测试,如果想兼容跟多版本,推荐使用第三种方式。
3、 第三种方法:先把状态栏变为透明,然后使顶部的view padding一个状态栏的高度。
这里我们先把ActionBar去掉,改为自定义的,如果不去掉,也可以直接用第二种方法修改ActionBar的颜色。首先去掉ActionBar,代码如下:
ActionBar actionBar = getSupportActionBar();
actionBar.hide();
自定义title.xml的布局,在根布局中设置背景颜色
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/top_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/bg_title_bar"
android:orientation="horizontal">
接着把title.xml布局include到每个activity中
获取状态栏高度:
public static int getStatusBarHeight(Context context) {
int statusHeight = -1;
try {
Class<?> clazz = Class.forName("com.android.internal.R$dimen");
Object object = clazz.newInstance();
int height = Integer.parseInt(clazz.getField("status_bar_height").get(object).toString());
statusHeight=context.getResources().getDimensionPixelSize(height);
} catch (Exception ex) {
ex.printStackTrace();
}
return statusHeight;
}
然后在setContentView(R.layout.activity_main);
后添加如下代码(设置状态栏透明,获取状态栏高度,让标题栏padding一个状态栏高度):
//set status translucent and set top view padding
protected void setImmerseLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
View topView = findViewById(R.id.top_view);
if (topView != null) {
int statusBarHeight = getStatusBarHeight(this.getBaseContext());
topView.setPadding(0, statusBarHeight, 0, 0);
}
}
}
在AndroidN上测试状态栏会有遮罩,在setContentView()之前添加如下代码:
//android N state bar TRANSPARENT
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
try {
Class decorViewClazz = Class.forName("com.android.internal.policy.DecorView");
Field field = decorViewClazz.getDeclaredField("mSemiTransparentStatusBarColor");
field.setAccessible(true);
field.setInt(getWindow().getDecorView(), Color.TRANSPARENT); //改为透明
} catch (Exception e) {}
}
如果想去掉沉浸效果,清除状态栏透明和padding效果即可。
//clear top view padding
public void clearImmerseLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
View topView = findViewById(R.id.top_view);
if (topView != null) {
topView.setPadding(0, 0, 0, 0);
}
}
}
完整代码如下:
public class MainActivity extends AppCompatActivity {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar actionBar = getSupportActionBar();
actionBar.hide();
//android N state bar TRANSPARENT
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
try {
Class decorViewClazz = Class.forName("com.android.internal.policy.DecorView");
Field field = decorViewClazz.getDeclaredField("mSemiTransparentStatusBarColor");
field.setAccessible(true);
field.setInt(getWindow().getDecorView(), Color.TRANSPARENT); //改为透明
} catch (Exception e) {}
}
setContentView(R.layout.activity_main);
setImmerseLayout();
}
//set status translucent and set top view padding
protected void setImmerseLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
View topView = findViewById(R.id.top_view);
if (topView != null) {
int statusBarHeight = getStatusBarHeight(this.getBaseContext());
topView.setPadding(0, statusBarHeight, 0, 0);
}
}
}
//获取状态栏高度
public static int getStatusBarHeight(Context context) {
int statusHeight = -1;
try {
Class<?> clazz = Class.forName("com.android.internal.R$dimen");
Object object = clazz.newInstance();
int height = Integer.parseInt(clazz.getField("status_bar_height").get(object).toString());
statusHeight = context.getResources().getDimensionPixelSize(height);
} catch (Exception ex) {
ex.printStackTrace();
}
return statusHeight;
}
//clear top view padding
public void clearImmerseLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
View topView = findViewById(R.id.top_view);
if (topView != null) {
topView.setPadding(0, 0, 0, 0);
}
}
}
}