温馨提示  2024年 6月我们已经停止开发者板块文章内容更新,谢谢来访。存档数据
知识 2023-10-08 20 次阅读

安卓开发疑问:如何重写DisplayCutout?

安卓开发中的DisplayCutout是最近几年以来逐渐诞生和蓬勃发展的一种新技术,它能够专为屏幕显示区域进行切割,以实现更加灵活的界面设计和交互体验。
DisplayCutout通常用于在屏幕底部保留部分区域,以实现状态栏、导航栏等元素的隐藏,最终为用户提供更加沉浸式的视觉体验。除此之外,DisplayCutout还可以用于实现自定义的界面布局和交互方式,提高应用的个性化程度和用户体验。
在安卓开发中,使用DisplayCutout需要关注其属性和方法的使用,包括切割区域的位置和大小、状态栏的隐藏等。同时,还需要考虑应用适配和兼容性问题,以确保在不同设备和屏幕尺寸上的正常显示和运行。
总结下来,安卓开发中的DisplayCutout是一种非常实用的新技术,能够为开发者提供更加灵活和个性化的界面设计,提高应用的用户体验和竞争力。

在 安卓 9.0 及以上版本中,谷歌推出了 DisplayCutout API,这个 API 是为了适配全面屏手机而生的。DisplayCutout API 能够让开发者获取到屏幕中的刘海(或水滴屏)信息,以便于在应用中进行相应的适配。下面我们来详细介绍一下 DisplayCutout API 的原理和使用方法。

一、原理

在全面屏手机上,由于屏幕顶部或者底部有刘海或者水滴屏等特殊形状,因此需要在应用中进行适配。在 安卓 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 方法或者剪裁方法来适配布局,为了防止内容被刘海覆盖。