前言

前段时间帮朋友搞了一个app,中间没更新blog,项目上线后,要开始还技术债了,后面会针对项目中用到的技术点,整理出来,app 名字是 海豚记账,欢迎下载交流感兴趣的技术点。

一、序

Apple 一直在引领设计的潮流,自从 iPhone X 发布之后,”刘海屏” 就一直存在争议。不过不管你怎样,Android 也要跻入 “刘海屏” 的行列,尤其是 Android P 发布之后,也从系统级支持顶部凹槽屏幕设计。

很多厂商也在逐渐推出 “刘海屏” 设计的手机,在国内比较常见的就是 OPPO R15 和 华为 P20,VIVO。

屏幕不一样了,迎来的就是一些适配上的问题。今天就来聊聊,Android 的 “刘海屏”,以及我们如何去适配它。

二、刘海屏的背景介绍

2.1 背景介绍

刘海屏的外观,我想大家应该都有概念,不过不同厂商刘海屏的实现方式也有所不太,这一点需要先有个概念。

就现在市场上的情况来说,会区分成两类,一类是标准的 Android P Api,另外一类就是厂商在 Android P 以下的系统,做的特殊适配。

例如:华为 P20 就是采用的 Android P 标准 Api 的方式,而 OPPO R15 就不一样了,它有自己的适配 Api。

2.2 那些需要单独适配

就算是增加了刘海屏,你也可以发现,大部分都是“切割”的状态栏的区域,所以就面临了三种情况。

有状态栏的页面,不会收到刘海屏的影响。

全屏未适配刘海屏的页面,系统会对刘海屏区域进行切割,让整体 UI 页面做下移处理,避开刘海屏的显示。

全屏已适配刘海屏的页面,可以兼容刘海屏,做到真正的全屏显示。

后面会单独讲解这几种方式的区别。

2.3 抢先体验 Android P

在手边没有对应系统的设备的时候,模拟器是一条不错的路,最近 Google 也发布了 Android P 的模拟器,还有一个办法就是找一些支持真机云测的平台,租用一台需要的远程设备,也是一个解决方案。

我这里选择 Android P 的模拟器,有需要自己更新 SDK ,无脑下载更新就好。

刘海的凹槽区域,大部分是为了给摄像头或者其他传感器留出区域。而在没有刘海的设备或者模拟器上,可以通过开发者选项 -Drawing 里的 “Simulate a display with a cutout”,开启刘海屏的支持。

如果你把所有的模式都试过一遍,你会发现,其实刘海屏的刘海,在 Android P 上,是有多种样式的,并非统一的。

2.4 刘海屏的适配

我们在全屏的页面,需要单独开启支持刘海屏。而 Google 提供的适配方案,可以设置是否在全屏模式下,使用刘海屏的区域。

WindowManager.LayoutParams lp=getWindow().getAttributes();lp.layoutInDisplayCutoutMode =            WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;getWindow().setAttributes(lp);

新的布局属性 layoutInDisplayCutoutMode 包含三种可选的模式,

    public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS = 1;    public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT = 0;    public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER = 2;

3 刘海屏的高度

在全屏模式下,我们需要有办法获取到刘海屏凹槽的高度,才可以做到设计和布局的时候,留出安全距离。

虽然 Google 要求,刘海屏的凹槽,必须和刘海的高度保持一致,而刘海屏又被隐藏在状态栏了,所以有一个思路是直接获取状态栏的高度,来判断刘海之外,可布局的安全区域。

不过 Android P 已经预留出了标准的测量 刘海屏凹槽 的 Api:DisplayCutout。

刘海屏的凹槽,就在屏幕的中间,所以只有 getSafeInsetTop() 方法返回的结果,是我们需要的,而其他的 getSafeInsetXxx() 方法,直接返回的是 0 。

view.postDelayed(new Runnable() {    @Override    public void run() {        DisplayCutout displayCutout = view.getRootWindowInsets().getDisplayCutout();        Log.i("cxmyDev", "SafeInsetBottom:" + displayCutout.getSafeInsetBottom());        Log.i("cxmyDev", "SafeInsetLeft:" + displayCutout.getSafeInsetLeft());        Log.i("cxmyDev", "SafeInsetRight:" + displayCutout.getSafeInsetRight());        Log.i("cxmyDev", "SafeInsetTop:" + displayCutout.getSafeInsetTop());    }}, 100);

得到的结果,也可以看一下:

I/cxmyDev: SafeInsetBottom:0I/cxmyDev: SafeInsetLeft:0I/cxmyDev: SafeInsetRight:0I/cxmyDev: SafeInsetTop:112

像 OPPO 这样的厂商,实现刘海屏的方式,也并不是按照 Android P 的标准做的,它完全是自己修改了刘海屏的实现方式。不过好在,都是会提供完备的适配文档,这就需要我们直接阅读他们提供的开发文档来进行适配。

oppo 的刘海屏适配文档:

对于 OPPO 而言,它刘海的高度是固定的,就是 80px。


判断当前设备是否是刘海屏,也提供了对应的 Api,可以用以下方法获取。

context.getPackageManager().hasSystemFeature(“com.oppo.feature.screen.heteromorphism”)
返回 true 为刘海屏,但是这种方法只能识别 OPPO 品牌所支持的刘海屏

四、结语

看完本篇文章,我想你对 Android 的刘海屏也有一定的认识了。这是一个全新的适配技术,现在还不确定不同厂商会不会对其微调,所以你要是碰到什么问题,不妨在留言区留言讨论。

更多相关文章

  1. Android开发系列三:Android中怎么实现底部菜单栏
  2. Android的.9.png图片分析
  3. 我的Android进阶之旅------>Android使用9Patch图片作为不失真背
  4. Android设计中的.9.png与Android(安卓)Studio中的设置
  5. android TextView 显示不全的问题解决,此问题是设置了maxLines和e
  6. 【.9.img】Android设计中的.9.png
  7. 【Android】Android(安卓).9 图介绍及制作
  8. android中如何让一个不知道高度的控件正好恰在上下两个控件之中
  9. 触摸屏(TP)乱跳原因总结

随机推荐

  1. ch023 Android ContentProvider(第一部分
  2. Android配置文件中标签
  3. Android单元测试
  4. android全屏显示
  5. Android多点触控
  6. Linux/Android(安卓)多点触摸支持
  7. Android ExpandableList
  8. android状态栏工具类
  9. 【魔幻塔防】22关配置文件
  10. 【魔幻塔防】128关配置文件