Android8.0 以后【凹口屏】得到迅速发展,目前已有了挖孔屏/水滴屏/刘海屏等各式各样的屏幕,究其根本依旧是【凹口屏】,单华为一个品牌就涵盖了基本所有类型,而对于屏幕适配也是不可逃避的问题。和尚单独对华为各型号屏幕进行适配尝试,部分方法可通用到其他品牌设备,为 Android 标准 SDK 方法。

其实凹口屏已经出现很久了,对于获取凹口宽高的方式也有很多种,但是以前主流的凹口屏中凹口位置一般是位于屏幕正上方,但随着发展,也出现了在左上角的挖孔屏样式。相应的,Android 9.0 即 SDK28 也发布了获取凹口屏的方法。

Android 9.0 以下适配方案

对华为设备凹口屏适配情况来说,若仅需获取凹口位置的宽高,如下方法即可,在 Android 各版本中均可(Android 9.0 及以上亦可)。此时获取屏幕水平方向安全位置时,可根据屏幕宽度-凹口宽度再左右均分即可。

/**

* 华为凹口屏判断方法 Android 各版本均可

* @param context

* @return

*/

public static boolean hasNotchInScreen(Context context){

boolean ret = false;

try {

ClassLoader cl = context.getClassLoader();

Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");

Method get = HwNotchSizeUtil.getMethod("hasNotchInScreen");

ret = (boolean) get.invoke(HwNotchSizeUtil);

} catch (ClassNotFoundException e) {

Log.e(TAG, "hasNotchInScreen ClassNotFoundException");

} catch (NoSuchMethodException e) {

Log.e(TAG, "hasNotchInScreen NoSuchMethodException");

} catch (Exception e) {

Log.e(TAG, "hasNotchInScreen Exception");

} finally {

return ret;

}

}

/**

* 华为凹口屏宽高获取方式 int[]{width, height}

* @param context

* @return

*/

public static int[] getNotchSize(Context context){

int[] ret = new int[] { 0, 0 };

try {

ClassLoader cl = context.getClassLoader();

Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");

Method get = HwNotchSizeUtil.getMethod("getNotchSize");

ret = (int[]) get.invoke(HwNotchSizeUtil);

} catch (ClassNotFoundException e) {

Log.e(TAG, "getNotchSize ClassNotFoundException");

} catch (NoSuchMethodException e) {

Log.e(TAG, "getNotchSize NoSuchMethodException");

} catch (Exception e) {

Log.e(TAG, "getNotchSize Exception");

} finally {

notchWidth = ret[0];

notchHeight = ret[1];

return ret;

}

}

Android 9.0 及以上适配

对于华为新出的挖孔屏设备基本均为 Android 9.0 及以上,Android 9.0 提供了对凹口屏相关的 SDK,谷歌认为凹口位置可以不固定位置也不固定个数,但是对于设备一条边只能有一个;如下方法对于 Android 9.0 及以上设备判断均可。SDK 不仅可以判断是否为凹口屏,同时可以获取各个凹口大小及所在位置。

步骤如下:

升级 build.gradle 中 compileSdkVersion 或 targetSdkVersion 为 28;

在 Application 或 Activity 中设置 meta-data 属性,和尚测试不设置亦可;

根据如下方法获取相应参数;

if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {

getSupportActionBar().hide();

getWindow().getDecorView()

.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | 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);

getWindow().getDecorView()

.findViewById(android.R.id.content)

.getRootView()

.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判断是否凹口手机

isNotchScreen = false;

} else {

List rects = cutout.getBoundingRects();

if (rects == null || rects.size() == 0) {

Log.e(TAG, "rects==null || rects.size()==0, is not notch screen");

isNotchScreen = true;

} else {

Log.e(TAG, "rect size:" + rects.size());//注意:凹口的数量可以是多个

isNotchScreen = true;

for (Rect rect : rects) {

notchRight = rect.right;

notchLeft = rect.left;

notchTop = rect.top;

notchBottom = rect.bottom;

notchWidth = notchRight - notchLeft;

notchHeight = notchBottom - notchLeft;

safeLeft = cutout.getSafeInsetLeft();

safeRight = cutout.getSafeInsetRight();

safeTop = cutout.getSafeInsetTop();

safeBottom = cutout.getSafeInsetBottom();

}

}

}

return windowInsets;

}

});

}

注意事项:

和尚在设置 Application 或 Activity 的主题为 NoActionBar 样式,此时要去掉 getSupportActionBar().hide(); 否则会报空指针异常;

@null

如下设置全屏使用凹口屏时要注意 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN,否则参数很有可能获取不到;

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | 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);

设置主题 NoActionBar 或代码中动态设置 getSupportActionBar().hide(); 展示效果在 Android 9.0 以下有部分差异,如下:

NoBarTheme 主题样式⬆️

AppTheme 主题样式⬆️

对于凹口屏适配还有很多机型要单独处理,以上仅对华为设备进行参考;如果有不对的地方还希望多多指出。以下是和尚公众号,欢迎闲来吐槽~

android 中间凹背景_Android 华为凹口屏适配小结相关推荐

  1. 【Android 屏幕适配】异形屏适配 ① ( 异形屏类型:刘海屏、水滴屏、挖孔屏 | 沉浸式布局刘海屏适配 | 华为手机异形屏适配注意点 )

    文章目录 一.异形屏类型:刘海屏.水滴屏.挖孔屏 二.沉浸式布局刘海屏适配 三.华为手机异形屏适配注意点 屏幕适配参考文档 : 设备兼容性概览 屏幕兼容性概览 支持不同的像素密度 声明受限屏幕支持 异 ...

  2. android 中间凹背景_Android开发仿百度地图的凹陷BottomNavigationView

    释放双眼,带上耳机,听听看~! 百度的: 71529789c6c948803e1075c2c7e00809.jpg 我的: e9347423eb2031228af77ad63d7b01d7.jpg 使 ...

  3. android 中间凹背景_Android实现边缘凹凸的View

    转载 最近做项目的时候遇到一个卡劵的效果,由于自己觉得用图片来做的话可以会出现适配效果不好,再加上自己自定义view方面的知识比较薄弱,所以想试试用自定义View来实现.但是由于自己知识点薄弱,一开始 ...

  4. android shape 按钮背景_Android button, xml文件定义形状,代码中修改背景颜色

    1. 首先在drawable文件夹定义一个shape.xml文件,内容如下: xmlns:android="http://schemas.android.com/apk/res/androi ...

  5. android shape 按钮背景_Android UI:XML文件配置按钮等背景方案

    (1)在开发中,我们经常会遇到一些纯色或带边框的简单样式的按钮或div,很多时候,都是用九宫格的背景图片来贴上去.但仔细想来,使用图片也带来了一些性能上的问题,包括过多的图片文件会导致渲染页面的时候需 ...

  6. Unity Android手机曲面屏、全面屏全屏适配

    最近项目在适配市面上各种手机,发现小米Mix2和三星的手机不能全屏播放总会有黑边 向这样 解决方案 <meta-data android:name="android.max_aspec ...

  7. android刘海屏适配方案

    刘海屏屏幕适配 注:以下所述"刘海"指延伸至状态栏的屏幕区域. 1. google 官方对Android P刘海屏的适配方案 google官方已经在**Android 9(API ...

  8. Android P 凹口屏支持,打造全面屏体验

    作者: Megan Potoski, Android 系统用户界面产品经理 智能手机发展至今,边框越做越窄,屏幕中横比越做越大.而凹口屏 (又称 "刘海屏") 更是成为各大设备厂商 ...

  9. Android刘海屏适配全方案(华为、小米、Vivo、Oppo)

    前言 目前市面上的刘海屏和水滴屏手机越来越多了,颜值方面是因人而异,有的人觉得很好看,也有人觉得丑爆了,我个人觉得是还可以.但是作为移动开发者来说,这并不是一件好事,越来越多异形屏手机的出现意味着我们 ...

最新文章

  1. googleearthpro打开没有地球_人在月球上睡24小时, 相当于地球多少年? 科学家的回答出乎意料...
  2. es6 日期字符串转日期_量化数据预处理-中文日期(含)转英文日期
  3. linuxtar.gz安装方法
  4. 基于双向LSTM和迁移学习的seq2seq核心实体识别
  5. COCOS2D-X 抖动效果 CCShake
  6. java中判断字段真实长度(中文2个字符,英文1个字符)的方法
  7. zhajinhuagame为了迎接新版
  8. Java讲课笔记04:变量与常量
  9. SAP License:搞砸SAP项目的3种方法
  10. 一个关于Show窗口与Invalidate();顺序问题
  11. vlan间路由的三种方法
  12. 速率法和终点法的区别_两点法终点法速率法.doc
  13. 社区说|Flutter 主流状态管理框架 provider get 分析
  14. Ubuntu下 百度在线语音合成使用
  15. 新型的Hbb项目目录结构
  16. 第一次Java课小结
  17. 遥望星空补丁工具 V1.7
  18. ue 编写linux脚本,通过什么工具编写shell脚本更方面直观
  19. 搜索引擎不收录网站页面的常见原因
  20. 拓展SOUI中SImRichEdit控件的视频OLE控件(VideoOle)

热门文章

  1. volatile、synchronized、(原子、可见、有序)、先行发生原则
  2. javascript / node.js / npm install 时 --save 和 --save-dev 的区别
  3. 启明云端1.54寸串口屏使用经验分享
  4. php里注册管理员账号,WordPress中创建用户角色的相关PHP函数使用详解
  5. Altium designer中元器件库(SCHLIB)元件引脚上文字(标号)大小及距离边缘位置设置
  6. php web开发应用教程,PHP-Web 应用程序开发:使用模板_PHP
  7. mysql授权用户主机_MySQL用户授权(GRANT)
  8. gyp linux,gyp编译工具
  9. Tesseract-OCR 字符识别---样本训练 [转]
  10. 以太坊钱包开发系列3 - 展示钱包信息及发起签名交易