maxAspectRatio
根据谷歌兼容性(CTS)标准要求,应用必须按以下方式中的任意一种,在AndroidManifest.xml中配置方可全屏显示,否则将以非全屏显示。
方式一:配置支持最大高宽比
* <meta-data android:name="android.max_aspect" android:value="ratio_float" />
* android:maxAspectRatio="ratio_float" (API LEVEL 26)
说明:以上两种接口可以二选一,ratio_float = 屏幕高 / 屏幕宽 (如oppo新机型屏幕分辨率为2280 x 1080, ratio_float = 2280 / 1080 = 2.11,建议设置 ratio_float为2.2或者更大)
方式二:支持分屏,注意验证分屏下界面兼容性
android:resizeableActivity="true"
建议采用方式二适配支持全面屏。
详见官方文档:https://source.android.google.cn/compatibility/cdd?hl=zh-cn
重要提醒
- 如果应用要支持分屏功能,则直接采用方式二,既支持了分屏,又适配和兼容了全面屏;
- 如果应用不支持分屏功能,设置了android:resizeableActivity="false" ,则必须采用方式一来适配全面屏,否则会出现如下问题:
全面屏不适配出现的问题
底部虚拟导航栏可能会透明或者是黑色的,原因是因为app的布局最大比例不够,不能够自动适配,如下图:
所以当视频播放器全屏的时候,会看有右边圈出的部分有间隔,无法铺满全屏
如果代码中设置之后,则能自动铺满全屏,不会透明或者预留间距:
<meta-data
android:name="android.max_aspect"
android:value="2.2" />
看如下效果图:
Android P全面屏适配
// 谷歌官方提供的默认适配刘海屏
WindowManager.LayoutParams lp =getWindow().getAttributes();
lp.layoutInDisplayCutoutMode=WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
getWindow().setAttributes(lp);
// 窗口声明使用刘海区域
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;
Android P获取刘海高度
刘海屏的凹槽,就在屏幕的中间,所以只有getSafeInsetTop()方法返回的结果,是我们需要的,其他的正常返回0
class WindowInsets {
DisplayCutout getDisplayCutout();
}
class DisplayCutout {
int getSafeInsetLeft();
int getSafeInsetTop();
int getSafeInsetRight();
int getSafeInsetBottom();
Region getBounds();
}
华为手机适配
官网地址:https://mini.eastday.com/bdmip/180411011257629.html
//判断是否是华为刘海屏
public static boolean isHuaweiScreenHasGroove(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 (Exception e) {
} finally {
return ret;
}
}
//获取华为刘海的高宽
public static int[] getHuaweiNotchSize(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 (Exception e) {
} finally {
return ret;
}
}
Oppo刘海适配
官网地址:https://open.oppomobile.com/wiki/doc#id=10159
//判断手机是否有刘海
public static boolean isOppoScreenHasGroove(Context context) {
boolean isHasGroove = context.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism");
return isHasGroove;
}
刘海高度固定:80px
VIVO手机刘海适配
官网地址:https://dev.vivo.com.cn/doc/document/info?id=103
//判断是否是voio刘海屏
public static final int NOTCH_IN_SCREEN_VOIO = 0x00000020;//是否有凹槽
public static final int ROUNDED_IN_SCREEN_VOIO = 0x00000008;//是否有圆角
public static boolean isVoioScreenHasGroove(Context context) {
boolean ret = false;
try {
ClassLoader cl = context.getClassLoader();
Class FtFeature = cl.loadClass("com.util.FtFeature");
Method get = FtFeature.getMethod("isFeatureSupport", int.class);
ret = (boolean) get.invoke(FtFeature, NOTCH_IN_SCREEN_VOIO);
} catch (Exception e) {
} finally {
return ret;
}
}
四周圆角高度:25dp
刘海高度:27dp
状态栏高度:32dp