简介:

随着去年iPhone X的发布,今年android厂商也紧随其后,发布了各种异形屏手机(国内习惯称为刘海屏),作为Android的东家,google也是大力支持这种方案,然后就决定在系统级予以支持,所以从Android P开始,就提供了相应的接口,适配刘海屏,并且华为和小米已经明确说明了,以后的新系统会兼容google官方的解决方案,所以接下来,我就介绍一下官方的解决方案。

适配方案:

1.官方特性介绍

谷歌称刘海屏为凹口屏以及屏幕缺口支持, 下面的内容摘自:https://developer.android.com/preview/features#cutout

Android P 支持最新的全面屏以及为摄像头和扬声器预留空间的凹口屏幕。 通过全新的 DisplayCutout 类,可以确定非功能区域的位置和形状,这些区域不应显示内容。 要确定这些凹口屏幕区域是否存在及其位置,请使用 getDisplayCutout() 函数。

全新的窗口布局属性 layoutInDisplayCutoutMode 让您的应用可以为设备凹口屏幕周围的内容进行布局。 您可以将此属性设为下列值之一:

(1)LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT

(2)LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES

(3)LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER

您可以按如下方法在任何运行 Android P 的设备或模拟器上模拟屏幕缺口:

(1)启用开发者选项。

(2)在 Developer options 屏幕中,向下滚动至 Drawing 部分并选择 Simulate a display with a cutout。

(3)选择凹口屏幕的大小。

注:我们建议您通过使用运行 Android P 的设备或模拟器测试凹口屏幕周围的内容显示。

2.相关接口介绍

(1)获取刘海尺寸相关接口:

https://developer.android.com/reference/android/view/DisplayCutout

方法 接口说明
List getBoundingRects() 返回Rects的列表,每个Rects都是显示屏上非功能区域的边界矩形。设备的每个短边最多只有一个非功能区域,而长边上则没有。
int getSafeInsetBottom() 返回安全区域距离屏幕底部的距离,单位是px。
int getSafeInsetLeft () 返回安全区域距离屏幕左边的距离,单位是px。
int getSafeInsetRight () 返回安全区域距离屏幕右边的距离,单位是px。
int getSafeInsetTop () 返回安全区域距离屏幕顶部的距离,单位是px。

(2)设置是否延伸到刘海区显示接口:
https://developer.android.com/reference/android/view/WindowManager.LayoutParams#layoutInDisplayCutoutMode

方法 接口说明
int layoutInDisplayCutoutMode 默认值:
LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
其他可能取值:
LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER

https://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES

常量 常量说明
int LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT 只有当DisplayCutout完全包含在系统状态栏中时,才允许窗口延伸到DisplayCutout区域显示。
int LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER 该窗口决不允许与DisplayCutout区域重叠。
int LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 该窗口始终允许延伸到屏幕短边上的DisplayCutout区域。

3.代码实现

(1)设置使用刘海区显示代码:

//使内容出现在status bar后边,如果要使用全屏的话再加上View.SYSTEM_UI_FLAG_FULLSCREENgetWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); //设置页面全屏显示WindowManager.LayoutParams lp = getWindow().getAttributes();lp.layoutInDisplayCutoutMode =        windowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; //设置页面延伸到刘海区显示getWindow().setAttributes(lp);

(2)获取刘海屏安全显示区域和刘海尺寸信息:

getWindow().getDecorView().setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {    @Override    public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {        DisplayCutout cutout = windowInsets.getDisplayCutout();        if (cutout == null) {            Log.e(TAG, "cutout==null, is not notch screen");//通过cutout是否为null判断是否刘海屏手机        } else {            List rects = cutout.getBoundingRects();            if (rects == null || rects.size() == 0) {                Log.e(TAG, "rects==null || rects.size()==0, is not notch screen");            } else {                Log.e(TAG, "rect size:" + rects.size());//注意:刘海的数量可以是多个                for (Rect rect : rects) {                    Log.e(TAG, "cutout.getSafeInsetTop():" + cutout.getSafeInsetTop()                            + ", cutout.getSafeInsetBottom():" + cutout.getSafeInsetBottom()                            + ", cutout.getSafeInsetLeft():" + cutout.getSafeInsetLeft()                            + ", cutout.getSafeInsetRight():" + cutout.getSafeInsetRight()                            + ", cutout.rects:" + rect                    );                }            }        }        return windowInsets;    }});

UI适配

1.判断是否为刘海屏

见上边代码

2.调整布局

如果是刘海屏,调整布局避开刘海区。

布局原则:保证重要的文字、图片、视频信息、可点击的控件和图标,应用弹窗等,建议显示在状态栏区域以下(安全区域)。如果内容不重要或者不会遮挡,布局可以延伸到状态栏区域(危险区域)。

建议按照如下布局原则修改:

3.获取状态栏高度

经过试验研究,小米和华为的获取的高度就是刘海的高度,并且在不同状态下这个值会有所变化

public static int getStatusBarHeight(Context context) {    int result = 0;    int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");    if (resourceId > 0) {        result = context.getResources().getDimensionPixelSize(resourceId);    }    return result;}

更多相关文章

  1. 目前 Android平板所面临的几个问题
  2. 在Android里如何判断一个指定的经纬度点是否落在一个多边形区域
  3. Android(安卓)6.0新特性之WebView不能适配屏幕解决方案
  4. 一些关于android屏幕的小知识
  5. UI效果(9): 屏幕相关操作
  6. HTC Desire HD (G10)初体验
  7. Android(安卓)UI 之 各种长度单位
  8. Android重力感应基础
  9. [UI控件问题] android屏幕自适应 android 属性

随机推荐

  1. android values 资源说明
  2. Android开发通知栏的那些事
  3. 【Android】第6章(3) AlertDialog(警告对话
  4. Android进程保活学习记录
  5. Android长按连续触发的具体实现
  6. android 在xml布局文件中 ImageView Imag
  7. Android字体大小设置自适应屏幕分辨率
  8. Android——FragmentPagerAdapter中fragm
  9. Android中实现可滑动的Tab的3种方式
  10. Android本地实现搜索历史记录