Android 9.0劉海屏適配

參考文章
Demo地址

全屏狀態下

全屏的狀態中,狀態欄是不存在的,系統默認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);
  1. LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULTLAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER不許延申到劉海效果,劉海那片區域是黑色的.

在這裏插入圖片描述

  1. 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);

最終得到得效果如下:

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章