小窗口/分屏形式

首先来看看什么是小窗口形式,如下图:

Android小窗口/分屏形式适配
  目前运用小窗口形式的或许会比较多,就我个人而言,我也常常运用小窗口形式,真的是方便,不用来回切换两个应用,所以适配方面,仍是引荐进行适配的。

判别当前是否处于小窗口形式/分屏形式

// 是否是小屏/分屏形式
public static boolean isInMultiWindowMode(Context context) {
    if (RomUtils.isOppo())
        return isInMultiWindowModeCheckOppo(context);
    else {
        boolean isInMultiWindowMode = false;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            if (context instanceof Activity) {
                return ((Activity) context).isInMultiWindowMode();
            }
        }
        return false;
    }
}
private static boolean isInMultiWindowModeCheckOppo(Context context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        ///获取App界面宽高
        WindowManager localWindowManager =
                (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        WindowMetrics currentWindowMetrics = localWindowManager.getCurrentWindowMetrics();
        int height = currentWindowMetrics.getBounds().height();
        int width = currentWindowMetrics.getBounds().width();
        L.i("app check window width: " + width + " height: " + height);
        ///获取屏幕宽高
        Display display = context.getDisplay();
        if (display != null) {
            int physicalHeight = context.getDisplay().getMode().getPhysicalHeight();
            int physicalWidth = context.getDisplay().getMode().getPhysicalWidth();
            L.i("app check window physicalWidth: " + physicalWidth + " physicalWidth: " + physicalHeight);
            return width != physicalWidth || height != physicalHeight;
        }
    }
    return false;
}

经实测:oppo的小窗口形式仍是会回来false,只有分屏形式才会回来true,小米/华为/vivo的小窗口形式/分屏形式均回来true。问了oppo技术支持,oppo这边只能通过判别宽高尺度来区别出小窗口/分屏形式。

界面适配

  小窗口/分屏形式是体系默认敞开支持的,界面来说其实就是类似小屏幕,仅仅这个小窗口的宽高比要比小屏幕的还要小,所以需求进行适配,不然或许显现不全,或许有哪些逻辑导致溃散,都是会呈现的呢。
  1、首先说下想要禁用的方法:
AndroidManifest.xml文件中的application节点或许activity节点中增加如下:

android:resizeableActivity="false" // 体系默认为true

  2、敞开功用的话,则需求进行适配了,适配区别两种情况:
  2.1、第一种是界面是列表类型的,可以进行上下翻滚,切换成小窗口形式也能完全展现出来的,则这种情况可以不用去适配界面;或许界面内容很少,切换成小窗口后所有控件同样能完全展现出来的也可以不用去适配界面。这时候,直接在AndroidManifest.xml的Activity中增加以下特点:

android:configChanges="keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"

该特点增加“screenLayout”可以避免在切换小窗口形式和正常形式时,Activity界面从头创立的问题,因为界面能直接复用完全展现,所以也自然无需从头创立从头布局了。
  2.2、第二种是界面是,切换成小窗口形式后,界面显现不完好,而且又不能通过翻滚进行查看,这时候就需求对界面进行从头布局以匹配小窗口形式的大小了。在AndroidManifest.xml的Activity中android:configChanges里边不要增加”screenLayout”选项,这时候,切换成小窗口形式,或许从小窗口形式切换回普通形式,会回调Activity/Fragment的onConfigurationChange方法。
  写在前面,有个比较严重的点需求留意,通过国内厂商的魔改,逻辑效果会有点不同:

小窗口形式需求留意:
华为:
activity.isInMultiWindowMode小窗口形式回来true
切换小窗口形式不会调用onConfigurationChanged,会调用onResume
小窗口形式顶部有个状态栏,布局内容在状态栏下
小窗口形式底部没有操作栏
vivo:
activity.isInMultiWindowMode小窗口形式回来true
切换小窗口形式会调用onConfigurationChanged,不会调用onResume
小窗口形式顶部有个状态栏,状态栏掩盖在布局内容上
小窗口形式底部没有操作栏
oppo:
activity.isInMultiWindowMode小窗口形式回来false (问了技术支持,只能通过宽高尺度来判别)
切换小窗口形式会调用onConfigurationChanged,不会调用onResume
小窗口形式顶部有个状态栏,状态栏掩盖在布局内容上
小窗口形式底部没有操作栏
小米:
activity.isInMultiWindowMode小窗口形式回来true
切换小窗口形式会调用onConfigurationChanged,不会调用onResume
小窗口形式顶部有个状态栏,状态栏掩盖在布局内容上
小窗口形式底部有个操作栏
小窗口形式PopupWindow的showAsDropDown展现的位置反常,只能运用showAtLocation
状态栏高度读取反常:切换小窗口形式切换回来后,状态栏高度读取到的值变小了  105->98
底部导航栏高度读取反常:小窗口形式,一开始读取到130,跳转其他页面后回退读取到142
三星:
直接抛弃...和国内的厂商不同,国内的宽高比是固定的,而三星可以随意修正小窗口的宽高,导致适配....无解,这种适配起来,就杂乱多了,需求每次切换了大小就从头核算布局。

  因为切换形式会回调其中一个生命周期(onConfigurationChanged/onResume),所以可以在回调的地方进行布局调整,适配界面直到能完好展现悉数UI。目前来说,小米的适配是麻烦多了,和其它厂商差别会比较大,所以不能一致适配。

弹窗Dialog/PopupWindow留意

  在实际开发过程中还发现,如果是以上2.2的情况,切换小窗口形式时,Dialog/PopupWindow有或许会被收回为null,但界面上仍是展现着,这时候对弹窗的操作都是无效的,而且还或许引发溃散,所以在Activity/Fragment的onDestroy里边,将界面内的弹窗悉数进行dismiss隐藏,避免呈现该问题。

完结

  因为我测验运用的仅仅各个厂商中的一两台手机,所以或许还不是很完全,或许还有其他情况需求适配,这就要比及遇到的时候再来了。
  总的来看,小窗口形式/分屏形式需求进行适配的,并不杂乱,监听生命周期调一调界面即可。