android4.4开始支持设置透明状态栏
在代码中设置
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
通过查看WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
的官方注释,有这么一句话
When this flag is enabled for a window, it automatically sets the system UI visibility flags {@link View#SYSTEM_UI_FLAG_LAYOUT_STABLE} and {@link View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}.
也可以这么设置
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
当然也可以在values-v19/styles.xml,values-v21/styles.xml和values-v23/styles.xml中设置
//使布局侵入到状态栏,并且使状态栏透明。不会出现状态栏显示隐藏的过渡动画效果。
<item name="android:windowTranslucentStatus">true</item>
fitsSystemWindows
这个属性会使布局下移一个状态栏高度的距离,避免布局侵入到状态栏
如何使状态栏颜色和头布局保持一致
1. 如果布局头部是一个ImageView
这种情况下,ImageView侵入到状态栏,如果没有大的影响,其实可以不做处理.否则,建议做出的图片,其内容能尽量下移一下,避免被状态栏遮挡过多.android5.0以后可以通过Palette获取bitmap的颜色,来给预留的view设置颜色.
1.1 添加依赖
implementation 'com.android.support:palette-v7:27.1.1'
1.2 获取图片颜色并设置给预留view
//预留view
final View insetView = null;
//头部imageView
final Bitmap bitmap = null;
Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
@Override
public void onGenerated(@NonNull Palette palette) {
Palette.Swatch mutedSwatch = palette.getMutedSwatch();
if (null!=mutedSwatch){
insetView.setBackgroundColor(mutedSwatch.getRgb());
}else {
Palette.Swatch vibrantSwatch = palette.getVibrantSwatch();
if (vibrantSwatch!=null){
insetView.setBackgroundColor(vibrantSwatch.getRgb());
}
}
}
});
2.如果布局头部是个标题栏
2.1 在布局头部放置一个0dp高度的View
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_orientation="vertical">
<View android:layout_width="match_parent"
android:layout_height="0dp"
android:id="@+id/insetView"
>
</View>
<FrameLayout
android:layout_width="match_parent"
android:id="@+id/content"
android:layout_height="0dp"
android:layout_weight="1">
</FrameLayout>
</LinearLayout>
2.2 在代码里获取状态栏高度
/**
* 获取状态栏高度
* @param context
* @return
*/
protected int getStatusBarHeight(Context context) {
int result = 0;
int resId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
result = context.getResources().getDimensionPixelOffset(resId);
}
return result;
}
2.3 设置预留view的高度和颜色
protected void setStatusHeightAndBackgroundColor(int height ,int color){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) insetView.getLayoutParams();
layoutParams.height = height;
insetView.setLayoutParams(layoutParams);
insetView.setBackgroundColor(ContextCompat.getColor(this,color));
}
}
以上这样处理,在小米8刘海屏幕上也能完美适配
各大厂手机适配地址
oppo
vivo
识别小米手机
MIUI6沉浸式状态栏
MIUI 9 & 10“状态栏黑色字符”实现方法变更通知