android 开发displaycutout
在 Android 9.0 及以上版本中,谷歌推出了 DisplayCutout API,这个 API 是为了适配全面屏手机而生的。DisplayCutout API 可以让开发者获取到屏幕中的刘海(或水滴屏)信息,以便于在应用中进行相应的适配。下面我们来详细介绍一下 DisplayCutout API 的原理和使用方法。
一、原理
在全面屏手机上,由于屏幕顶部或者底部有刘海或者水滴屏等特殊形状,因此需要在应用中进行适配。在 Android 9.0 及以上版本中,谷歌推出了 DisplayCutout API,这个 API 可以让开发者获取到屏幕中的刘海信息,以便于在应用中进行相应的适配。
具体来说,DisplayCutout API 主要通过以下两种方式获取刘海信息:
1. 通过 WindowInsets#getDisplayCutout() 方法获取 DisplayCutout 对象,该对象包含了刘海的位置和大小信息。getDisplayCutout() 方法返回的 DisplayCutout 对象可能为 null,表示当前屏幕不存在刘海或者水滴屏等特殊形状。
2. 通过 WindowInsets#getSystemWindowInsetTop() 方法获取状态栏的高度,该高度包含了刘海的高度。如果状态栏的高度大于 0,则说明当前屏幕存在刘海或者水滴屏等特殊形状。
二、使用方法
下面我们来介绍一下如何使用 DisplayCutout API 来适配全面屏手机。
1. 获取 DisplayCutout 对象
我们可以通过 WindowInsets#getDisplayCutout() 方法获取 DisplayCutout 对象,该对象包含了刘海的位置和大小信息。如果当前屏幕不存在刘海或者水滴屏等特殊形状,则 getDisplayCutout() 方法会返回 null。
下面是一个简单的示例代码:
```
View rootView = getWindow().getDecorView().getRootView();
rootView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
@Override
public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
DisplayCutout displayCutout = windowInsets.getDisplayCutout();
if (displayCutout != null) {
// 处理刘海信息
}
return windowInsets;
}
});
```
在这个示例代码中,我们通过 rootView 的 setOnApplyWindowInsetsListener() 方法来监听 WindowInsets 的变化。当 WindowInsets 发生变化时,我们可以通过 getDisplayCutout() 方法获取 DisplayCutout 对象,从而获取刘海的位置和大小信息。
2. 处理刘海信息
获取到 DisplayCutout 对象后,我们可以通过以下方法获取刘海的位置和大小信息:
- getSafeInsetTop():获取刘海顶部安全区域的高度。
- getSafeInsetBottom():获取刘海底部安全区域的高度。
- getSafeInsetLeft():获取刘海左侧安全区域的宽度。
- getSafeInsetRight():获取刘海右侧安全区域的宽度。
下面是一个简单的示例代码:
```
View rootView = getWindow().getDecorView().getRootView();
rootView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
@Override
public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
DisplayCutout displayCutout = windowInsets.getDisplayCutout();
if (displayCutout != null) {
int safeInsetTop = displayCutout.getSafeInsetTop();
int safeInsetBottom = displayCutout.getSafeInsetBottom();
int safeInsetLeft = displayCutout.getSafeInsetLeft();
int safeInsetRight = displayCutout.getSafeInsetRight();
// 处理刘海信息
}
return windowInsets;
}
});
```
在这个示例代码中,我们通过 getSafeInsetTop()、getSafeInsetBottom()、getSafeInsetLeft() 和 getSafeInsetRight() 方法来获取刘海的位置和大小信息。
3. 适配布局
获取到刘海的位置和大小信息后,我们可以通过以下方式来适配布局:
- Padding 方式:在布局中添加 padding,以避免内容被刘海覆盖。
- Margin 方式:在布局中添加 margin,以避免内容与刘海重叠。
- 剪裁方式:可以通过 setClipToPadding() 方法或者 setClipChildren() 方法来剪裁布局,以避免内容被刘海覆盖。
下面是一个简单的示例代码:
```
View rootView = getWindow().getDecorView().getRootView();
rootView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
@Override
public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
DisplayCutout displayCutout = windowInsets.getDisplayCutout();
if (displayCutout != null) {
int safeInsetTop = displayCutout.getSafeInsetTop();
int safeInsetBottom = displayCutout.getSafeInsetBottom();
int safeInsetLeft = displayCutout.getSafeInsetLeft();
int safeInsetRight = displayCutout.getSafeInsetRight();
// 适配布局
view.setPadding(safeInsetLeft, safeInsetTop, safeInsetRight, safeInsetBottom);
}
return windowInsets;
}
});
```
在这个示例代码中,我们通过 setPadding() 方法来给 rootView 添加 padding,以避免内容被刘海覆盖。
总结
DisplayCutout API 是为了适配全面屏手机而生的,通过该 API,开发者可以获取到屏幕中的刘海信息,以便于在应用中进行相应的适配。在使用 DisplayCutout API 时,我们需要注意以下几点:
- 通过 WindowInsets#getDisplayCutout() 方法获取 DisplayCutout 对象,该对象包含了刘海的位置和大小信息。getDisplayCutout() 方法返回的 DisplayCutout 对象可能为 null,表示当前屏幕不存在刘海或者水滴屏等特殊形状。
- 通过 DisplayCutout#getSafeInsetTop()、getSafeInsetBottom()、getSafeInsetLeft() 和 getSafeInsetRight() 方法来获取刘海的位置和大小信息。
- 可以通过 Padding 方式、Margin 方式或者剪裁方式来适配布局,以避免内容被刘海覆盖。