1.setSystemUiVisibility()
int flag =
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION //隐藏导航栏
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION//不隐藏导航的情况下,将Activity的显示范围扩展到导航栏底部,但是Activity的底部内容会被遮挡.
| View.SYSTEM_UI_FLAG_FULLSCREEN//隐藏状态栏 如果需要一直隐藏 可以使用WindowManager.LayoutParams.FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN//不隐藏状态栏的情况下 将Activity内容显示在状态栏下 ,但是内容会被遮挡
| View.SYSTEM_UI_FLAG_IMMERSIVE//避免用户交互导致清楚全屏状态,配合全屏时使用
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY//避免某些⽤户交互造成系统⾃动清除全屏状态。同时Activity的部分内容也因此被StatusBar覆盖遮挡。
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE//稳定布局,在动态显示隐藏 状态栏导航栏的情况下,系统为设置了fitSysetmWindow=true的View固定Padding值.使内容不上下移动
;
getWindow().getDecorView().setSystemUiVisibility(flag);
2.fitSystemWindow
只有个设置了View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 或者View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 时 fitSystemWindow=true才有效
3.WindowManager属性
1. WindowManager.FLAG_TRANSLUCENT_STATUS 设置状态栏透明
会自动设置 View.SYSTEM_UI_FLAG_LAYOUT_STABLE和SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
2. WindowManager.FLAG_FULLSCREEN 隐藏状态栏, 会忽略输入法的SOFT_INPUT_ADJUST_RESIZE
3. WindowManager.FLAG_TRANSLUCENT_NAVIGATION 半透明导航栏
会自动设置View.SYSTEM_UI_FLAG_LAYOUT_STABLE和View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
4. WindowManager.FLAG_DRAWS_SYSTEM_BAR_VACKGROUNDS为导航栏和状态栏设置背景颜色
将导航栏状态栏设置透明色,并且将所在的空间设置成window.getStatusBarColor()和window.getNavigationBarColor() 的颜色
5.使用SOFT_INPUT_ADJUST_RESIZE
同时View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN或View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION时,当键盘弹出时,只会tSystemWindow=true的view所占区域会被resize,其他view将会被软键盘覆盖。
4.安全区域下显示内容
public static void setDisplayCutoutShortEdges(Window window) {
if (window == null) {
return;
}
// LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 才可以使用刘海区显示
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
WindowManager.LayoutParams lp = window.getAttributes();
// 应用如果想让布局延伸到刘海区显示,设置 LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES属性使用刘海区显示
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
}else{
lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
}
window.setAttributes(lp);
}
}
4.设置全屏模式代码
下面代码可以设置 1-2-3步骤展示全屏 也可以设置 1-4步骤展示全屏
1. //安全区域下显示内容
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
WindowManager.LayoutParams lp = getWindow().getAttributes();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
}else{
lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
}
getWindow().setAttributes(lp);
}
2. //全屏模式
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
3. //全屏模式如果不设置上面的WindowManager.LayoutParams.FLAG_FULLSCREEN 用户交互会退出全屏
int flag =
View.SYSTEM_UI_FLAG_FULLSCREEN |//隐藏状态栏 如果需要一直隐藏 可以使用WindowManager.LayoutParams.FLAG_FULLSCREEN
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | //隐藏导航栏
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |//不隐藏状态栏的情况下 将Activity内容显示在状态栏下 ,但是内容会被遮挡
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |//不隐藏导航的情况下,将Activity的显示范围扩展到导航栏底部,但是Activity的底部内容会被遮挡.
View.SYSTEM_UI_FLAG_LAYOUT_STABLE //稳定布局,在动态显示隐藏 状态栏导航栏的情况下,系统为设置了fitSysetmWindow=true的View固定Padding值.使内容不上下移动
;
4.
int flag =
View.SYSTEM_UI_FLAG_FULLSCREEN |//隐藏状态栏 如果需要一直隐藏 可以使用WindowManager.LayoutParams.FLAG_FULLSCREEN
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | //隐藏导航栏
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |//不隐藏状态栏的情况下 将Activity内容显示在状态栏下 ,但是内容会被遮挡
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |//不隐藏导航的情况下,将Activity的显示范围扩展到导航栏底部,但是Activity的底部内容会被遮挡.
View.SYSTEM_UI_FLAG_LAYOUT_STABLE //稳定布局,在动态显示隐藏 状态栏导航栏的情况下,系统为设置了fitSysetmWindow=true的View固定Padding值.使内容不上下移动
//用户windowmanger m没有设置全屏状态下不设置下面两个flag 会交互导致退出全屏,需要加下边的flag 保证不退出全屏
View.SYSTEM_UI_FLAG_IMMERSIVE//避免用户交互导致清楚全屏状态,配合全屏时使用
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY//避免某些⽤户交互造成系统⾃动清除全屏状态。同时Activity的部分内容也因此被StatusBar覆盖遮挡。
;
5. 修改状态栏导航栏颜色
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS|WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
getWindow().setStatusBarColor(Color.RED);
getWindow().setNavigationBarColor(Color.GREEN);
6.设置状态栏导航栏字体颜色
12 以上
WindowInsetsControllerCompat controller = ViewCompat.getWindowInsetsController(activity.getWindow().getDecorView());
if (controller != null) {
double v = ColorUtils.calculateLuminance(xxxx);
//状态栏字体色
controller.setAppearanceLightStatusBars(v>0.5f);
//导航栏字体色
controller.setAppearanceLightNavigationBars(v>0.5f);
controller.show(WindowInsetsCompat.Type.statusBars()|WindowInsetsCompat.Type.navigationBars());
controller.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_DEFAULT);
}
double v = ColorUtils.calculateLuminance(xxxxx);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
if (v>0.5f){
newVis = newVis | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
getWindow().getDecoview().setSystemUiVisibility(newVis)
}
}
7.显示/隐藏导航栏状态栏
androidR 以上可以使用
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
getWindow().setDecorFitsSystemWindows(true);
WindowInsetsController controller = getWindow().getInsetsController();
if (controller != null) {
controller.show(WindowInsets.Type.statusBars());
controller.show(WindowInsets.Type.navigationBars());
controller.show(WindowInsets.Type.systemBars());
//
controller.hide(WindowInsets.Type.statusBars());
controller.hide(WindowInsets.Type.navigationBars());
controller.hide(WindowInsets.Type.systemBars());
//这块还可以设置BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE,设置画这个之后 左滑返回需要两次才能响应退出页面
controller.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_DEFAULT);
}
}
其他版本可以参考# setSystemUiVisibility 使用方式.
8. 安全区域的位置获取
主要是摄像头的位置
public static void checkScreenSafeArea(Window window, final View decorView) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
decorView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
@Override
public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
DisplayCutout cutout = windowInsets.getDisplayCutout();
if (cutout != null) {
// Rect 非功能区域 可以是多个 一般是只有一个
List<Rect> list = cutout.getBoundingRects();
if (list != null && !list.isEmpty()) {
Rect rect = list.get(0);
if (rect != null) {
int height = rect.height();
//可以根据Rect 的left right 判断安全区域的大概位置,再结合分屏以及浮窗模式判断是否需要在此区域内显示内容
}
}
}
return windowInsets;
}
});
}
}