小米8刘海屏适配

1.前言

最近在开发一个小说阅读器APP,在阅读界面碰到了适配问题,把解决问题的方法及过程记录一下。因为我只有小米8一个测试机,所以方法不保证其他手机的兼容性,只是提供一个思路,希望能给到其他人帮助。

2.全面屏适配

在Android 7.0以后,google提供了在通过在AndroidManifest.xml文件中进行声明android:resizeableActivity = “true” 来开启分屏模式的开关,且自动适应了全面屏。此外,我们可以手动设置最大屏幕宽高比。

android8.0及以上:

<activity android:maxAspectRatio="2.1">
 ...
</activity>

android7.1及以下版本:

<meta-data android:name="android.max_aspect" android:value="2.1" />

value值需要大于等于2.1,需要注意的是,如果手动进行设置了最大宽高比,一定要将多窗口模式设置为false,否则不生效。

3.刘海屏适配

从Android P开始,google提供了刘海屏适配的方案,提供了全新的 DisplayCutout 类,通过 DisplayCutout 类可以确定非功能区域的位置和形状。我们可以通过使用DisplayCutout 类中的getSafeInsetLeft ()、getSafeInsetRight ()、getSafeInsetTop ()、getSafeInsetBottom ()来分别获取安全区域距离屏幕左边、右边、上方、下方的距离,单位是px。

View decorView = getWindow().getDecorView();

decorView.post(new Runnable() {
            @Override
            public void run() {
                DisplayCutout displayCutout = decorView.getRootWindowInsets().getDisplayCutout();
                displayCutout.getSafeInsetLeft();
                displayCutout.getSafeInsetRight();
                displayCutout.getSafeInsetTop();
                displayCutout.getSafeInsetBottom();
});

除此此外,从Android P开始,google在WindowManager中新增了layoutInDisplayCutoutMode 布局参数属性,包含三种模式:

//默认情况,全屏页面不可用刘海区域,非全屏页面可以进行使用
public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT = 0;
//不允许使用刘海区域
public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER = 2;
//允许页面延伸到刘海区域
public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES = 1;

因为我需要开发的是一个小说阅读界面,使用刘海区域会导致不太美观,因此我采用了不允许使用刘海区域 的模式。

4.小米8(MIUI10)获取宽高

在开发小说阅读界面时,因为界面的绘制是通过获取屏幕的宽高来实现的,所以需要获取手机的宽和高。网上较多获取宽高的方法是通过下面实现的:

WindowManager manager = this.getWindowManager();
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
int width = outMetrics.widthPixels;
int height = outMetrics.heightPixels;
int density = outMetrics.density;

但是使用该方法获取宽高后,在我的手机下方会出现一个黑条,很不美观。原因是因为该方法获取的是去除虚拟按键(导航栏)后的宽高,因为我的手机是使用的全面屏手势,没有使用虚拟按键,因此我们需要使用

manager.getDefaultDisplay().getRealMetrics(outMetrics);

来获取包含虚拟按键的宽高。

但是因为前面所说,我使用了不允许使用刘海屏的模式,因此会造成View下移,出现View超出屏幕的情况。我们知道是因为刘海屏的问题造成的,因此我们只需要去除刘海屏的高度便可以了。

此外,因为Build.VERSION.SDK_INT >= 28 时,才能调用官方接口,因此我们可以减去状态栏高度的方法进行适配,但是此方法仅适用于刘海屏高度小于状态栏高度的问题。

WindowManager manager = this.getWindowManager();
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
int tempWidth = outMetrics.widthPixels;
int tempHeight = outMetrics.heightPixels;
int tempDensity = outMetrics.density;
int resourceId  = BookApp.mContext.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId >0 && resourceId != null) {
    int statusBarHeight = BookApp.mContext.getResources().getDimensionPixelSize(resourceId);
    if (statusBarHeight!=null)
        tempHeight = (int)(tempHeight- (statusBarHeight / tempDensity + 0.5f)); //将dip转为px然后减去
}

 

猜你喜欢

转载自blog.csdn.net/Magic1an/article/details/87923845