全屏狀態下
全屏的狀態中,狀態欄是不存在的,系統默認DecorView佈局
不會延申到劉海區域.
設置全屏
// 去除標題
requestWindowFeature(Window.FEATURE_NO_TITLE);
// WindowManager.LayoutParams.FLAG_FULLSCREEN: 讓window進行全屏顯示
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
判斷是否爲劉海屏
private boolean hasDisplayCutout(Window window) {
DisplayCutout displayCutout;
View rootView = window.getDecorView();
WindowInsets insets = rootView.getRootWindowInsets();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && insets != null) {
// 獲取顯示切口
displayCutout = insets.getDisplayCutout();
if (displayCutout != null) {
// 如果切口不爲null
if (displayCutout.getBoundingRects() != null && displayCutout.getBoundingRects().size() > 0 && displayCutout.getSafeInsetTop() > 0) {
// 1. 如果切口區域集合不爲null
// 2. 切口區域存在
// 3. 安全區域距離頂部距離不爲0
// 三個條件滿足,則屏幕中存在劉海.
return true;
}
}
}
return false;
}
設置內容是否能延申到劉海區
WindowManager.LayoutParams params = window.getAttributes();
// LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT 全屏模式,內容下移,非全屏不受影響
// LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 全屏模式,允許內容區域延伸進劉海區
// LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER 全屏模式,不允許內容區域延伸進劉海區
params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
window.setAttributes(params);
LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
與LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
不許延申到劉海效果,劉海那片區域是黑色的.
LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
允許延申到劉海效果,劉海那片區域是白色的.
將內容延申到劉海區
將內容延申到劉海區需要設置沉浸式狀態欄,說明下,如果上一步設置的是內容區域步延申到劉海區的話,這一步沉浸式狀態欄就算設置了也是不能起到作用的.
// View.SYSTEM_UI_FLAG_FULLSCREEN: 狀態欄隱藏
// View.SYSTEM_UI_FLAG_HIDE_NAVIGATION: 導航欄隱藏
// View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN: 視圖延伸至狀態欄區域,狀態欄上浮於視圖之上
int flags = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
int visibility = window.getDecorView().getSystemUiVisibility();
visibility |= flags; //追加沉浸式設置
window.getDecorView().setSystemUiVisibility(visibility);
最終的效果就是:
非全屏狀態下
非全屏狀態下,狀態欄是存在的(默認劉海區高度與狀態欄高度相等).此時將內容區域延申到劉海區(也就是狀態欄區域)做法如下.
去除標題
requestWindowFeature(Window.FEATURE_NO_TITLE);
設置內容區域延申到劉海區
// 設置狀態欄顏色透明
getWindow().setStatusBarColor(Color.TRANSPARENT);
// 這個標記的意思是繪製一個背景透明的狀態欄,然後用StatusBarColor中的顏色去填充,上面一步已經設置了StatusBarColor的顏色.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
// 最後還要清楚清除這個標記
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN: 視圖延伸至狀態欄區域,狀態欄上浮於視圖之上
// SYSTEM_UI_FLAG_LIGHT_STATUS_BAR: 設置狀態欄中字體與圖標顏色爲黑色.
int flags = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR|View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
int visibility = getWindow().getDecorView().getSystemUiVisibility();
visibility |= flags;// 追加屬性
getWindow().getDecorView().setSystemUiVisibility(visibility);
最終得到得效果如下: