折叠屏适配

参考文章


1. 折叠屏简介

1.1 诞生的背景

手机屏幕​目前的整体发展趋势是​大屏化​,大屏化主要表现在两方面:​屏幕面积​的增大,​屏占比​的提高。但是目前这两方面已经发展的相当成熟,很难再有大的突破。

折叠屏手机​的出现不仅实现了​屏幕尺寸增加​,同时还满足​携带方便​的需求,有效解决大屏和便携矛盾,未来或将成为手机发展的重要方向之一?

1.2 折叠屏手机结构

折叠屏的主要结构由​柔性屏​与​铰链​组成,利用全新的柔性屏技术,可实现屏幕的弯曲和折叠。折叠屏手机一般都有一个折页或者铰链,将两个显示屏分开,带有铰链的设备可以在铰链后面跨越内容,有些设备还可以半折叠或者翻盖,支持折叠和部分折叠状态。但通常,我们见到的折叠屏手机都是由1整块AMOLED屏组成,并且铰链位置可以显示画面。
在这里插入图片描述

除此之外,还有双屏手机​(屏幕由2块组成,铰链区域不可显示画面),也被称为折叠屏手机,如:微软2020年9月推出的基于Android 10.0系统的Surface Duo。

在这里插入图片描述

目前流行的就是这三种: ![在这里插入图片描述](https://img-blog.csdnimg.cn/06084f1882824b76ace2c3037fe888e0.png)

1.3 折叠屏手机市场规模

2020国内智能手机销量约​3亿​部,而同期全球的折叠屏手机出货量仅​194.73 万​部,三星以**71.59%​的市场份额占据全球折叠屏市场第一,华为市场份额​10.56%**位居第二。

从销量来说,折叠屏市场占有依然比较小众,主要原因在于折叠屏手机目前良品率还不够高,产能受限,进而导致手机售价过高(华为Mate X 的AMOLED屏供应商为京东方,京东方折叠屏良品率数据为:2018,65%;2021,85%);同时,软件方面,大部分软件还未进行完全适配,影响用户体验。

2. 折叠屏适配发展

2.1 基础屏幕适配(包括折叠屏)

2.1​.1 灵活布局​

使用​​wrap_content​​、​​match_parent​​避免硬编码
使用 ​​ConstraintLayout​​做根布局,方便屏幕尺寸变化,视图自动移动和拉伸

2.1​.2 备用布局​

布局文件使用宽度、屏幕方向限定符(​​port​​​ 或 ​​land​​)单独适配
Fragment界面组件

2.1​.3 图片资源

图片采用.9图、矢量图

2.2 折叠屏手机适配

其主要经历了三个重要阶段。

2.2.1 Android官方折叠屏适配指南

2018年8月Google发布Android 9.0,首次支持折叠屏功能,并推出了​ ​Android官方折叠屏适配指南​​。主要从以下几个方面进行适配:

  1. 应用连续性:处理配置变更
  2. 屏幕兼容性:​​resizeableActivity​​​ 与 ​​maxAspectRatio​​
  3. 多窗口适配:多项恢复与专属资源访问

2.2.2 厂商补充适配方案

各厂商陆续发布自己的折叠屏手机,以及补充的适配方案。不同折叠屏手机上,拥有各自研发的一些独有功能,要想体验这些独特功能,就需要使用厂商的方案进行适配。代表有:三星、华为、Microsoft Surface Duo等

2.2.3 Google 2021 I/O 发布​​Jetpack WindowManager​​等库

2021年5月,Google I/O开发者大会推出专门用于折叠屏适配的库 ​​Jetpack WindowManager​​ 1.0,以及更新了已有的一些库如:​​SlidingPaneLayout​​、​​NavRail​​等,以便应用更便捷的适配折叠屏功能。

3. Android 官方折叠屏适配指南

主要参考 ​ ​官方文档《为可折叠设备构建应用》

Android 10 (API 级别 29) ,Google就已经对折叠屏提供了“Screen Continuity(屏幕连续性)”的原生系统支持,并将这项技术称之为:Foldables。

所谓屏幕连续性,就是在可折叠设备上运行时,应用可以自动从一个屏幕转换到另一个屏幕,并且当前任务能在转换后继续无缝执行,系统会在转换时触发配置变更。

3.1 应用连续性:处理配置变更

在默认情况下,折叠屏折叠变化时(或应用从一个屏幕转到另一个屏幕),系统会销毁并重新创建整个 ​​Activity​​。

但我们希望屏幕变化之后,程序能够以切换前的状态继续运行,不需要重启页面。我们可以给 ​​Activity​​​ 添加​​configChanges​​配置:

<activity
 		android:configChanges="smallestScreenSize|screenSize|screenLayout" />

应用内监听变化,根据当前窗口大小,调整布局大小和位置:

    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // 获取当前窗口配置信息,调整布局大小
    }

如果需要重启 ​​Activity​​​才能完成适配的场景,可以通过​​onSaveInstanceState()​​​与​​onRestoreInstanceState()​​​ 或 ​​ViewModel对象​​来进行之前状态保存和后续的恢复。

3.2 屏幕兼容性

在Anroid 11版本中,对折叠屏的支持进行了增强性扩展,为开发者适配折叠屏应用提供了更多的接口。

3.2.1 应用大小可调:resizeableActivity
  1. 应用能够在多窗口模式下运行
  2. 应用的大小可动态调整

设置 resizeableActivity=true 即可实现此目的。
这可以为应用可能遇到的任何设备类型和环境(例如可折叠设备、桌面模式或自由窗口)提供最大兼容性。当系统编译设置​​target​​ >= ​24(Android 7.0)​ 不需要手动设置,系统默认为 ​​true​​,支持多窗口和调节尺寸。
如果应用设置 resizeableActivity=false,则会告知平台其不支持多窗口模式。
但是系统还是可能会调整应用的大小或将其置于多窗口模式;要实现兼容性,便需要对应用中的所有组件(如应用的所有 Activity 等)应用同一配置。在某些情况下,重大变更(例如,显示屏尺寸更改)可能会重启进程,而不会更改配置。这时需要支持折叠屏连续性,需添加属性:

<meta-data android:name="android.supports_size_changes" android:value="true" />

例如,以下 Activity 设置了 resizableActivity=false 以及 maxAspectRatio。设备展开时,系统会将应用置于兼容模式,保以此来保持 Activity 配置,如大小和宽高比。

如果未设置 resizeableActivity,或将其设置为 true,系统会假定该应用完全支持多窗口并且可调整大小。

*注意:某些原始设备制造商 (OEM) 可能会在 Activity 的显示区域发生更改时,在屏幕上添加一个小型重启图标。为用户提供在新配置中重启 Activity 的机会。

3.2.2 屏幕宽高比

Android 10 (API 级别 29) 或更高版本 支持更多种宽高比。对于可折叠设备而言,设备类型可以是超长、超宽的屏幕(例如屏幕宽高比为 21:9 的折叠设备、 1:1 的屏幕)。

当​​resizableActivity=true​​​时设置​​maxAspectRatio​​ 无效;
而当​​resizeableActivity = false​时,使用​ ​maxAspectRatio​​​、​ ​minAspectRatio​​ 指定最小或最大纵横比,在设置的纵横比限制范围内,折叠屏会自动对尺寸进行调节,超出限制的进入兼容模式(黑边)。

如要兼容尽可能多的设备,推荐纵横比设置范围:[1, 2.4],即1:1到12:5。google推荐说 应该尽量多针对以下屏幕宽高比测试自己的应用:

在这里插入图片描述

3.3 多窗口模式

大屏幕的好处之一是能够运行多个窗口。也就是分屏,现在的技术可支持三个或更多应用同时在一个屏幕上运行,并且相互之间还可以共享内容:

如果应用不能妥善支持多窗口模式,则可以设置 resizeableActivity=false。

3.3.1 多页面恢复

多窗口的行为变化历史:

  • Android 7.0 支持分屏:左右/上下显示两个窗口
  • Android 8.0 支持画中画,此时处于画中画的​​Activity​​虽处于前台,但处于 ​​Paused​​状态
  • Android 9.0 (API 28) 及以下:多窗口下,只有获得焦点的应用是处于​​Resumed​​状态,其它可见​​Activity​​扔处于​​Paused​​状态
  • Android 10.0 (API 29) :多窗口模式时,所有​​Acttivity​​全部处于​​Resumed​​状态

在搭载 Android 9.0 及更低版本的设备上运行时,只有获得焦点的应用处于已恢复状态。任何其他可见 Activity 都处于已暂停状态。如果应用在处于暂停状态时关闭资源或停止内容,则可能会产生问题。

在 Android 10 中,对此做了优化,即当设备处于多窗口模式时,所有 Activity 都会保持已恢复状态。这称为多项恢复。
注意,如果顶部有透明 Activity,或者 Activity 不可成为焦点,则相应 Activity 可能会处于已暂停状态。

为解决Android 9.0及以下,只有获得焦点应用才处于​​Resume​​​状态,其它可见​​Activity​​​处于​​Paused​​状态问题。可添加下列属性,手动添加开启多项恢复。

<meta-data
    android:name="android.allow_multiple_resumed_activities" android:value="true" />

3.3.2 专属资源访问

为了帮助支持多项恢复功能,系统提供了一个新的生命周期回调

Activity#onTopResumedActivityChanged()

当 Activity 获得或失去顶部恢复 Activity 位置时,系统会调用此方法。当 Activity 使用共享的单一资源(例如麦克风或摄像头)时。

protected void onTopResumedActivityChanged(boolean topResumed) {
    if (topResumed) {
        // Top resumed activity
        // Can be a signal to re-acquire exclusive resources
    } else {
        // No longer the top resumed activity
    }
}

当我们使用了独占资源时就要用到这个方法。什么叫独占资源?麦克风、摄像头就是,这类资源同一时间只能给一个 ​​Activity​​​ 使用。以摄像头使用为例,在Android10上,官方建议使用 ​ ​CameraManager.AvailabilityCallback#onCameraAccessPrioritiesChanged()​​​监听摄像头是否可用。
当收到​​Activity#onTopResumedActivityChanged(isTopResumed)​​回调,且,

  • ​​isTopResumed = false​​ 时,需要在此时判断是否释放独占资源,而不必在一失去焦点时就释放资源;
  • ​​isTopResumed = true​​​ 时 ,可以申请独占的摄像头资源,原持有摄像头资源的应用将收到 ​ ​CameraDevice.StateCallback#onDisconnected()​​​ 回调。​

应用收到 CameraDevice.StateCallback#onDisconnected() 回调后,对摄像头设备进行的后续调用将抛出 CameraAccessException。

3.3.3 多窗口数据拖拽

借助 Android 拖放框架,用户可以通过交互式拖放手势来移动数据。用户可以在应用中的 View 之间拖动文本、图片、对象(可以通过 URI 表示的任何内容),也可以使用多窗口模式在应用之间拖动这些内容。
该框架包括拖动事件类、拖动监听器,以及程序类和方法。

在这里插入图片描述
详情见 官方文档《拖放》

4. 各大厂商适配

折叠屏厂商发布了对应适配文档的主要有:三星、华为、微软等。详情看下方链接:

5. 使用 Jetpack WindowManager 进行折叠屏适配

​​Jetpack WindowManager​​ 出现之前,折叠屏适配面临如下一些问题

折叠状态下应用体验较差:如半开状态、桌面模式等折叠姿态下,全屏画面扭曲。
无法正确识别折叠屏类型、可显示范围等。如微软的双屏折叠手机,中间部分无画面区域被铰链遮挡。
缺乏统一适配库支持,开发人员对于不同机型,适配比较繁琐,工作量较大。

为了帮助APP开发人员支持新的设备尺寸,并为新旧平台版本上的各种​​Window Manager​​​功能提供通用的API交互。Android官方推出了​​Jetpack WindowManager​​,其优点:
  • 为所有类型的可折叠设备提供​统一​ ​API​,避免各设备单独适配。
  • 可折叠设备的物理属性的信息:​折叠屏类型​、​折叠状态​、​铰链方向​、​窗口显示范围​等信息。
  • 最初版本面向​可折叠设备​,将来扩展为支持更多的​显示类型​和​窗口功能。

5.1 Jetpack WindowManager API 使用

Jetpack WindowManager API的目标:

  • 为所有类型的可折叠设备提供​统一​ ​API​,避免各设备单独适配。
  • 可折叠设备的物理属性的信息:​折叠屏类型​、​折叠状态​、​铰链方向​、​窗口显示范围​等信息。

​​WindowManager​​ API 包含了以下内容:

  • ​​WindowLayoutInfo​​:包含了​窗口的显示特性​,例如该窗口是否可折叠或包含铰链。
  • ​​ FoldingFeature​​: 让您能够监听可折叠设备的​折叠状态​得以判断设备的​姿态。
  • ​WindowMetrics​​: 提供当前窗口或全部​窗口的显示指标

使用WindowManager适配的主要原理:通​过​​WindowManager​​获取折叠屏设备信息​​FoldingFeature​​信息,对于不同的折叠姿态,更新UI显示内容​。

​​FoldingFeature​​用来描述屏幕的折叠状态或两个物理显示面板之间的铰链状态。主要的API如下:

​​1.getType()​​:获取屏幕物理类型。

  • 值:​​TYPE_FOLD​​。表示屏幕为​无物理间隙​的柔性屏幕中的折叠。市面上大部分常见的折叠屏,如Samsung Fold、华为 Mate X。
  • 值:​​TYPE_HINGE​​。表示屏幕为带有​铰链​(不可显示区域)的两块屏幕,市面上目前比较少见,典型的指:Surface Duo

2.​​getState()​​​:折叠状态,主要有两种状态:

  • STATE_FLAT​​​(展开)
  • STATE_HALF_OPENED​​(半开)。

3.getBounds():折叠功能边界的 Rect 实例,指示折叠屏当前可显示的屏幕可见范围。

​​4.getOrientation():折叠屏铰链防线:

  • ​​ORIENTATION_HORIZONTAL​​​
  • ​​ORIENTATION_VERTICAL​​。

5.​​isSeparating()​​:内容区域是否分割为2块。

  • true:半开或双屏设备;
  • false:计算是否有遮挡

6. 测试、可折叠模拟器

模拟器支持折叠设备。开发者可在折叠情形下测试应用:

创建并运行。

测试。

… End!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值