Android小窗口/分屏模式适配

小窗口/分屏模式

首先来看看什么是小窗口模式,如下图:
  目前使用小窗口模式的可能会比较多,就我个人而言,我也经常使用小窗口模式,真的是方便,不用来回切换两个应用,所以适配方面,还是推荐进行适配的。

判断当前是否处于小窗口模式/分屏模式

scss 复制代码
// 是否是小屏/分屏模式
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节点中添加如下:

ini 复制代码
android:resizeableActivity="false" // 系统默认为true

2、开启功能的话,则需要进行适配了,适配区分两种情况:

2.1、第一种是界面是列表类型的,可以进行上下滚动,切换成小窗口模式也能完全展示出来的,则这种情况可以不用去适配界面;或者界面内容很少,切换成小窗口后所有控件同样能完全展示出来的也可以不用去适配界面。这时候,直接在AndroidManifest.xml的Activity中添加以下属性:

ini 复制代码
android:configChanges="keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"

该属性添加"screenLayout"可以避免在切换小窗口模式和正常模式时,Activity界面重新创建的问题,因为界面能直接复用完全展示,所以也自然无需重新创建重新布局了。

2.2、第二种是界面是,切换成小窗口模式后,界面显示不完整,并且又不能通过滚动进行查看,这时候就需要对界面进行重新布局以匹配小窗口模式的大小了。在AndroidManifest.xml的Activity中android:configChanges里面不要添加"screenLayout"选项,这时候,切换成小窗口模式,或者从小窗口模式切换回普通模式,会回调Activity/Fragment的onConfigurationChange方法。   写在前面,有个比较严重的点需要注意,经过国内厂商的魔改,逻辑效果会有点不同:

makefile 复制代码
小窗口模式需要注意:
华为:
切换小窗口模式不会调用onConfigurationChanged,会调用onResume
小窗口模式顶部有个状态栏,布局内容在状态栏下
小窗口模式底部没有操作栏

vivo:
切换小窗口模式会调用onConfigurationChanged,不会调用onResume
小窗口模式顶部有个状态栏,状态栏覆盖在布局内容上
小窗口模式底部没有操作栏

oppo:
切换小窗口模式会调用onConfigurationChanged,不会调用onResume
小窗口模式顶部有个状态栏,状态栏覆盖在布局内容上
小窗口模式底部没有操作栏

小米:
切换小窗口模式会调用onConfigurationChanged,不会调用onResume
小窗口模式顶部有个状态栏,状态栏覆盖在布局内容上
小窗口模式底部有个操作栏
小窗口模式PopupWindow的showAsDropDown展示的位置异常,只能使用showAtLocation
状态栏高度读取异常:切换小窗口模式切换回来后,状态栏高度读取到的值变小了  105->98

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

弹窗Dialog/PopupWindow注意

在实际开发过程中还发现,如果是以上2.2的情况,切换小窗口模式时,Dialog/PopupWindow有可能会被回收为null,但界面上还是展示着,这时候对弹窗的操作都是无效的,并且还可能引发崩溃,所以在Activity/Fragment的onDestroy里面,将界面内的弹窗全部进行dismiss隐藏,避免出现该问题。

完结

由于我测试使用的只是各个厂商中的一两台手机,所以可能还不是很完全,可能还有别的情况需要适配,这就要等到遇到的时候再来了。

总的来看,小窗口模式/分屏模式需要进行适配的,并不复杂,监听生命周期调一调界面即可。

相关推荐
Digitally28 分钟前
比较 iPhone:全面比较 iPhone 17 系列
android·ios·iphone
被开发耽误的大厨33 分钟前
鸿蒙项目篇-22-项目功能结构说明-写子页面和导航页面
android·华为·harmonyos·鸿蒙
安然~~~2 小时前
mysql多表联查
android·数据库·mysql
2501_915909065 小时前
HTTPS 错误解析,常见 HTTPS 抓包失败、443 端口错误与 iOS 抓包调试全攻略
android·网络协议·ios·小程序·https·uni-app·iphone
程序猿陌名!8 小时前
Android开发 AlarmManager set() 方法与WiFi忘记连接问题分析
android
骐骥19 小时前
2025-09-08升级问题记录: 升级SDK从Android11到Android12
android·android12·sdk31
CV资深专家12 小时前
Android 各分区模块编译配置(mk/bp)总结
android
louisgeek14 小时前
Java 线程池取消的方式
android
Billy_Zuo15 小时前
人工智能机器学习——模型评价及优化
android·人工智能·机器学习
tangweiguo0305198715 小时前
Flutter与原生混合开发:实现完美的暗夜模式同步方案
android·flutter