【Android折叠屏适配】基于AutoSize框架适配折叠屏并兼容多窗口模式

问题背景

当前最新的Android API 33对大屏设备的支持已较为完善,结合Jetpack Compose等响应式布局可实现一次适配所有屏幕。但考虑到代码往往是不能立即重构的,想要利用存量代码适配层出不穷的大屏及可折叠设备,并兼容多窗口场景,可采用Android界大名鼎鼎的AutoSize框架配合2套设计图尺寸来完成。

AutoSize框架基本原理

AutoSize框架支持5种单位 ,包括dp、sp、pt、in、mm,其中dp及sp为AutoSize框架的主单位。开发过程中可开启或关闭对某一单位的支持,使用主单位+副单位或只使用副单位进行适配都是可以的。选择哪一个副单位,撰写layout时就使用该单位即可。
AutoSize适配屏幕的核心原理为通过WindowManager拿到DisplayMetrics中的屏幕宽高(单位为px),再结合设置的设计图宽高(单位为px)计算并全局设置density(细节可查阅AutoSize框架源码)。

在Application及BaseActivity中进行设置

考虑到折叠屏开合时具有2组不同的屏幕宽高,我们针对其设置2套设计图宽高用以正确计算density。由于具有2套设计图尺寸,在AndroidManifest中设置设计图宽高不可行,需在Application onCreate()中计算当前屏幕宽高比及window宽高比手动设置设计图宽高,代码如下。
此外,在屏幕折叠及旋转场景下,从registerComponentCallbacks的onConfigurationChanged()回调中拿到的屏幕宽高有时不准确,尚未定位到原因(增加时延也并不稳定),故需在封装的BaseActivity的onConfigurationChanged()生命周期中也加入如下处理。

        /*注册屏幕适配监听器,适配前后均会回调此方法*/AutoSizeConfig.getInstance().setOnAdaptListener(new onAdaptListener() {@Overridepublic void onAdaptBefore(Object target, Activity activity) {if (activity == null) {return;}int[] windowSize = new int[2];windowSize[0] = activity.getResources().getDisplayMetrics().widthPixels;windowSize[1] = activity.getResources().getDisplayMetrics().heightPixels;AutoSizeConfig.getInstance().setCustomFragment(true).getUnitsManager().setSupportSP(false).setSupportDP(false).setSupportSubunits(Subunits.MM);/*判断屏幕宽高比是否为大屏*/if (FoldScreenUtil.isLargeScreen(activity)) {/*判断window宽高比是否为大窗口*/if (FoldScreenUtil.isLargeWindow(activity)) {Log.i("isLargeScreen", "isLargeWindow");/*判断横竖屏*/if (activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {/*大屏-大窗口-横屏设计尺寸*/AutoSizeConfig.getInstance().getUnitsManager().setDesignWidth(windowSize[0]).setDesignHeight(windowSize[1]).setDesignSize(1556, 1395);} else {/*大屏-大窗口-竖屏设计尺寸*/AutoSizeConfig.getInstance().getUnitsManager().setDesignWidth(windowSize[0]).setDesignHeight(windowSize[1]).setDesignSize(1395, 1556);}} else {if (activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {/*大屏-小窗口-横屏设计尺寸*/AutoSizeConfig.getInstance().getUnitsManager().setDesignWidth(windowSize[0]).setDesignHeight(windowSize[1]).setDesignSize(1556, 750);} else {/*大屏-小窗口-竖屏设计尺寸*/AutoSizeConfig.getInstance().getUnitsManager().setDesignWidth(windowSize[0]).setDesignHeight(windowSize[1]).setDesignSize(750, 1556);}}} else {/*小屏通常禁止旋转,仅设置竖屏设计尺寸即可*//*特殊情况:平行视窗下只能拿到当前activity的显示区域宽高,会被判定为小屏*/AutoSizeConfig.getInstance().getUnitsManager().setDesignWidth(windowSize[0]).setDesignHeight(windowSize[1]).setDesignSize(750, 1556);}}@Overridepublic void onAdaptAfter(Object target, Activity activity) {}});

注意:多窗口场景下Activity window与屏幕不等价

多窗口场景下(如平行视窗、分屏及悬浮窗等),window大小和屏幕大小并不等价,若在多窗⼝模式下仍是以屏幕的宽⾼进⾏适配,则density一定是不正确的值。而AutoSize框架中获取的宽高为屏幕宽高,因此,需利用Activity上下文拿到窗口大小并手动设置。
经测试,平行视窗较为特殊,拿到的屏幕宽高为当前activity显示的区域宽高。
可参考如下方法判断当前window是否为大窗口状态。

    public static boolean isLargeWindow(Activity activity) {if (activity == null) {return false;}float longSide = 0;float shortSide = 0;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {WindowMetrics windowMetrics = activity.getWindowManager().getCurrentWindowMetrics();Rect windowRect = windowMetrics.getBounds();longSide = Math.max(windowRect.width(), windowRect.height());shortSide = Math.min(windowRect.width(), windowRect.height());} else {int widthPixels = activity.getResources().getDisplayMetrics().widthPixels;int heightPixels = activity.getResources().getDisplayMetrics().heightPixels;longSide = Math.max(widthPixels, heightPixels);shortSide = Math.min(widthPixels, heightPixels);}boolean isLargeWindow = longSide / shortSide < MIN_ASPECT;Log.i("isLargeWindow", "longSide" + longSide + "shortSide" + shortSide);return isLargeWindow;}

在item的getView()或onBindViewHolder中进行设置

由于GridView、RecyclerView等组件存在item复用机制,屏幕开合或旋转时,item宽高可能不正确。在getView()中加入AutoSize.autoConvertDensityOfGlobal(activity)手动设置density可解决此问题。

【Android折叠屏适配】基于AutoSize框架适配折叠屏并兼容多窗口模式相关推荐

  1. 显示已连接启动传屏服务器,基于树莓派的无线传屏系统的设计与实现

    陈涛 陈辉金 摘要:无线传屏技术拟在无线的环境中,将客户端的屏幕信息,通过无线网络传输至服务器计算机上.相比与传统的视频共享或视频同步,无线传屏技术的优势为:所需的电缆少.终端可以随意移动,可提供更加 ...

  2. 基于bootstrap框架在ie8以下,兼容媒体查询[css样式]

    1 <style type="text/css"> 2 /*基于bootstrap框架在ie8以下,兼容媒体查询*/ 3 .row [class^="col- ...

  3. android分屏模式_Android多窗口模式(分屏模式)

    Android N 支持多窗口模式,或者叫分屏模式,即在屏幕上可以同时显示多个窗口. 在手机模式下,两个应用可以并排或者上下同时显示,如图 1 所示,屏幕上半部分的窗口是系统的 CLOCK 应用,下半 ...

  4. Android N 多窗口模式

    前言  在智能手机更新换代越来越快,手机屏幕越来越大,手机可以做的事情越来越多,人们已经离不开智能手机了,甚至有的人开始在用手机办公了.在大屏幕手机上,如果一个手机可以一边播放视频,一边上着网,那种体 ...

  5. 移动端适配指南!聊聊安卓折叠屏给交互设计和开发带来的变化

    移动端的时代前端同学面临着各种适配的处理.刘海机的出现,前端需要考虑刘海机适配.如今,随着折叠屏手机的面世,前端同学接着又要处理折叠屏幕的适配.本文除了介绍折叠机给我们带来的变化之外,还提出了响应式设 ...

  6. Android AutoSize屏幕适配中图标及字体放大的问题解决

    现象: 项目接入Android AutoSize屏幕适配框架,项目本身主界面是横屏操作的界面.测试中用户反馈在vivo x27的手机或者其他机型也会出现(没测试出来)横屏后所有的图标及字体都放大. 原 ...

  7. 基于android p的miui,小米8青春版开始适配基于Android P的MIUI10系统,米粉欢呼雀

    原标题:小米8青春版开始适配基于Android P的MIUI10系统,米粉欢呼雀 到目前为止小米8/屏幕指纹版.小米MIX 3.小米MIX 2S.小米MAX3等多款小米手机已经适配了安卓P系统.但是很 ...

  8. android大屏适配_Android 全面屏适配

    全面屏 mix.png 小米mix(18:9屏幕)的出现标志的Android手机进入全面屏时代,这个非主流的尺寸确实带来了更多的观赏性.虽然现在看起来可能已经没有那么惊艳了,但是想想他刚出现的时候超大 ...

  9. coloros基于java_行业首批适配 基于Android 11的ColorOS 11本月24日发布

    原标题:行业首批适配 基于Android 11的ColorOS 11本月24日发布 9月9日凌晨,谷歌发布Android11正式版,ColorOS 官方随即宣布面向 9 月 7 日成功参与版本招募的O ...

最新文章

  1. 【转载】xmind的使用安装方法
  2. python绘制简单直方图-python plotly绘制直方图实例详解
  3. python3 第三十四章 - 聊聊File对象
  4. 【线性筛】【质因数分解】【约数个数定理】hdu6069 Counting Divisors
  5. 高可用架构可行性方案
  6. 怎样打开计算机音频服务器,win10系统音频服务器未运行的修复步骤
  7. xpath 简单用法小记
  8. android listview添加数据_Android系统列表控件
  9. 计算机做镜像步骤,如何将当前的操作系统做成镜像?
  10. Layer1隐私项目BeamX DAO完成200万美元融资,Collider Ventures、AirSpeed18等机构参投
  11. Cisco小型局域网配置实验
  12. CMP?MSP?1+1才能大于2
  13. oracle10g配置tns,连接Oracle 10g时ORA-12514: TNS: 监听进程不能解析在连接描述符中给出的SID...
  14. 6种常用的项目管理模式
  15. sql server 代理权限问题
  16. 科学家研发真实版的《星际迷航》牵引光束
  17. DIY ROV系列(五)水下机器人通信系统
  18. 个人永久性免费-Excel催化剂功能第22波-Excel文件类型、密码批量修改,补齐PowerQuery短板...
  19. 我的世界在自建的服务器中装mod,《我的世界》中国版服务器MOD添加教程
  20. SqlServer 触发器 详细讲解

热门文章

  1. 学校机房中无法使用Todesk和向日葵控制寝室电脑,可以使用Parsec进行控制的步骤。
  2. Memcached应用总结
  3. 万能RecyclerView分割线扩展
  4. CSS学习之绘制几何图形
  5. 最常用的抖音直播话术大全,新手主播快收藏
  6. 如何做好会员管理与维护?
  7. Unity添加自发光材质
  8. 2D坐标系与3D坐标系的相互转换--python实现
  9. 我深爱的Java,对不起,我出轨了!!!呸!渣男!
  10. 北京信息科技大学计算机学院官网,北京信息科技大学教务处官网入口地址