服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - 详解Android 华为凹口屏适配小结

详解Android 华为凹口屏适配小结

2022-09-26 14:58阿策神奇 Android

这篇文章主要介绍了Android 华为凹口屏适配小结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

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

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

android 9.0 以下适配方案

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**
 * 华为凹口屏判断方法 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 华为凹口屏适配小结

详解Android 华为凹口屏适配小结

android 9.0 及以上适配

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

步骤如下: 升级 build.gradlecompilesdkversiontargetsdkversion28 ; 在 applicationactivity 中设置 meta-data 属性,小菜测试不设置亦可;

?
1
<meta-data android:name="android.notch_support" android:value="true"/>

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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<rect> 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;
      }
    });
}

详解Android 华为凹口屏适配小结

详解Android 华为凹口屏适配小结

详解Android 华为凹口屏适配小结

详解Android 华为凹口屏适配小结

注意事项: 小菜在设置 applicationactivity 的主题为 noactionbar 样式,此时要去掉 getsupportactionbar().hide(); 否则会报空指针异常;

?
1
2
3
4
<style name="nobartheme" parent="theme.appcompat.noactionbar">
 <item name="android:windownotitle">true</item>
 <item name="android:windowcontentoverlay">@null</item>
</style>

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

?
1
2
3
4
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 以下有部分差异,如下:

详解Android 华为凹口屏适配小结

noactionbar 主题

详解Android 华为凹口屏适配小结

apptheme 主题

对于凹口屏适配还有很多机型要单独处理,以上仅对华为设备进行参考;如果有不对的地方还希望多多指出。也希望大家多多支持服务器之家。

原文链接:https://www.jianshu.com/p/91d0fde0901f

延伸 · 阅读

精彩推荐