乐趣区

关于小程序:京东小程序折叠屏适配探索-京东云技术团队

前言

随着近年来手机行业的飞速发展,手机从性能机进入到智能机,手机屏幕占比也随着技术和零碎的提高越来越大,特地是 Android 10 推出当前,折叠屏逐步成为 Android 手机倒退的趋势。

图 1 Android 手机屏幕发展趋势

京东小程序近年来也反对了越来越多的业务和利用,做好小程序的折叠屏的适配也是合乎将来的发展趋势,能为用户和业务方提供更好的体验和价值。

Android 利用折叠屏适配摘要

利用在折叠屏运行时,能够从一个屏幕切换到另一个屏幕。利用应该做好配置变更的适配和界面状态的保留,以保障利用当前任务能无缝迁徙到转换后的屏幕,从而为用户提供杰出的连续性体验。

1.resizeableActivity

默认状况下,Activity resizableActivity 属性为 true,零碎假设该利用齐全反对多窗口并且可调整大小。

图 2 Android 手机折叠屏

如果您不心愿本人的利用在多窗口模式下调整大小,你能够设置 Activity resizableActivity 属性为 false,零碎会将利用置于兼容模式。某些原始设施制造商 (OEM) 可能会施行一项性能,即每当 Activity 的显示区域产生更改时,都会在屏幕上增加一个小型重启图标。这为用户提供了在新配置中重启 Activity 的机会。下图示例展现了一次内屏到外屏,外屏到内屏切换中零碎相干解决。

图 3 折叠屏利用重启示例

此外,用户须要“设置”-“显示”中关上利用的“在外屏上持续应用应用程序”开关,否则,切换到外屏时零碎将回到锁屏界面,利用会被压至后盾。不反对 resize 的利用会无奈关上此开关。

图 4 Android 折叠屏展现开关

2. 屏幕宽高比

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

如要与尽可能多的设施兼容,您应该尽量多针对以下屏幕宽高比测试本人的利用:

图 5 Android 手机屏幕宽高比

如果无奈反对上述某些高宽比,您能够应用 maxAspectRatio(同之前一样)以及 minAspectRatio 来指明本人利用能够解决的最高宽高比和最低宽高比。如果屏幕宽高比超出这些限度,利用可能会进入兼容模式。

3. 解决配置变更

某些设施配置可能会在运行时发生变化(例如屏幕方向、键盘可用性,以及当用户启用多窗口模式时)。产生这种变动时,Android 会重启正在运行的 Activity(先后调用 onDestroy() 和 onCreate())。重启行为旨在通过利用与新设施配置相匹配的备用资源来主动从新加载您的利用,从而帮忙它适应新配置。

如要妥善处理重启行为,Activity 必须复原其先前的状态。您能够同时应用 onSaveInstanceState()、ViewModel 对象以及长久存储,以在配置变更时保留并复原 Activity 的界面状态。

然而,您可能会遇到这种状况:重启利用并复原大量数据不仅老本昂扬,而且会造成蹩脚的用户体验。在此状况下,咱们通常能够自行处理配置变更,以防止系统资源变更引起 Activity 重启,通过在标签中增加 android:configChanges 申明实现。android:configChanges 属性文档中列出该属性的可能值。最罕用的值包含 “orientation”、”screenSize” 和 “keyboardHidden”等。

总之,为了做好 Android 利用的折叠屏适配,利用应能妥善地保留界面状态和反对配置变更,并进行具体的测试,具体适配领导计划能够参考官网文档。

小程序折叠屏适配现状

小程序不同于原生的 Android 利用,微信小程序框架目前是基于 webview 渲染,小程序逻辑层、视图层等进行相干视图、组件的计算渲染时依赖于获取到的设施尺寸数据,当屏幕尺寸发生变化时,不可避免的会造成布局款式的错乱。小程序业内目前还没有官网的折叠屏适配计划。以衰弱宝微信小程序为例,产生折叠后,不仅界面上存在问题,还存在无奈从历史工作栈中关上的问题。

图 6 微信利用 Android 手机折叠屏成果

此外,从微信开发社区咱们理解到,有不少开发者对于小程序折叠屏适配还是有诉求的。

图 7 微信小程序折叠屏适配诉求

京东小程序折叠屏适配

1. 京东小程序折叠屏问题

京东小程序也存在元素尺寸不适合、折叠后无奈从工作栈中再次关上等问题,咱们看一下京东快递小程序的景象。

图 8 京东小程序适配前

内屏关上小程序状态:

图 9 京东小程序适配前 - 内屏

内屏转外屏状态:

图 10 京东小程序适配前 - 内屏转外屏

外屏关上小程序状态:

图 11 京东小程序适配前 - 外屏

外屏转内屏状态:

图 12 京东小程序适配前 - 外屏 转内屏

总之,就是在无论是内屏还是外屏,首次关上时获取到的屏幕尺寸数据是对的,小程序能依照适宜的尺寸渲染元素;一旦产生折叠,在新的状态要么是元素过大不适宜窄屏,要么是元素过小不适宜宽屏。

那么问题来了,为什么在初试关上状态页面上的元素是大小适合的呢?

2. 小程序多屏幕适配

rpx(responsive pixel)响应单位

rpx 是微信小程序独有的、解决屏幕自适应的尺寸单位,在小程序开发中,举荐应用 rpx 这种响应式的像素单位进行开发

能够依据屏幕宽度进行自适应,不管大小屏幕,规定屏幕宽为 750rpx,以 iPhone6 为基准,iPhone6 的屏幕宽度为 375px,则 750rpx = 375px

实在设施获取到的物理像素是多种多样的,在小程序外部通过实在物理像素与 375 的比值失去缩放比例,真正渲染应用时再转换为对应的像素,通过 rpx 设置元素和字体的大小,小程序在不同尺寸的屏幕下,能够实现主动适配。

3. 折叠屏问题剖析

元素尺寸问题:

在折叠屏开展状态关上小程序,此时取到的设施尺寸等均为开展时的数据,屏幕折叠后,元素大小没有发生变化,然而承载小程序的容器大小变动了,屏幕变窄了,于是依照原有的尺寸,所有的布局空间产生压缩,导致页面挤压在一起。

同样的,在外屏关上小程序时获取到的尺寸数据是适宜外屏的,再折叠到内屏状态时也无奈及时更新到内屏的尺寸。

究其原因,在产生屏幕折叠时,小程序没有获取到最新的屏幕数据,无奈更新屏幕缩放比,同时没有机制告诉小程序进行从新渲染或加载。

无奈重启问题:

小程序在 Android 端运行在独立的过程中,不同小程序运行在不同过程,小程序引擎具备本人独有的管理机制。在之前屏幕折叠后小程序被杀死过程,通过历史工作栈无奈再次拉起该过程。

4. 解决思路

监听屏幕折叠:

1. 记录以后屏幕参数(宽、高、方向)

2. 在 onConfigurationChanged(Configuration newConfig) 回调中获取最新屏幕配置

当屏幕产生折叠后,零碎会将 newConfig 下发给应用程序,取出 newConfig.orientation、newConfig.screenWidthDp 和 newConfig.screenHeightDp,与 之前保留的屏幕参数进行比照。如果宽、高发生变化,通常认为屏幕产生折叠。

3. 细节解决

a. 因为视屏播放器全屏状态下通常会是横屏状态,当从全屏状态切回失常模式时往往会回到竖屏,这里屏幕的 orientation 会与之前的不同,不能当做折叠解决。

b. 折叠屏手机屏幕往往底部还有一个最近利用的快捷导航条,如果是开启状态,因为须要重汇的缘故,在产生折叠后,零碎会触发两次 onConfigurationChanged(Configuration newConfig) 回调,而且两次回调的参数中 newConfig.screenHeightDp 会前后不统一,这里须要做一下兼容解决,否则会误判为屡次折叠。

图 13 折叠屏导航条

图 14 折叠屏导航条 2

不同的底部导航条

元素尺寸问题:

要解决此问题,就要在辨认到屏幕尺寸发生变化时,及时告诉到业务,有两种计划:

1. 部分刷新:告诉业务自行刷新

这种计划能够在肯定水平上保留用户操作流程的残缺,然而也存在非以后页面无奈刷新或者或退后再次刷新等问题,对用户来说体验个别,而且须要小程序业务的开发者来监听页面变动,减少了开发者的业务复杂度。

2. 整体刷新:重启小程序

这种计划是客户端引擎监听到设施产生折叠时,敞开小程序,并进行从新关上。能够很好地保障页面的从新适配,重启行为会对用户操作流程完整性有肯定的伤害,对小程序开发者来说没有工作量。

无奈重启问题:

针对此问题,引擎侧须要防止杀死小程序所在过程,同时联合下面 2 个页面刷新计划,综合思考,采纳在以后过程整体刷新、重启小程序计划。一方面解决了历史工作栈无奈重启问题,另一方面防止了创立新过程的开销,界面上给人的感官也更流程。

5. 遇到的问题及解决方案

1.multiWindow、pictureInPicture 问题

Android 零碎还有两个性能就是多窗口和画中画模式,activity 能够缩放为一个小窗口,在屏幕中显示一小块区域,可能很灵便的拉伸缩放,对于此,小程序引擎疏忽了窗口大小的变动,否则用户只有一缩放就会重启小程序,这是咱们和用户都无奈承受的。这种状况下,放弃不变是符合多窗口的设计初衷的,读者在解决相似的适配计划时该当留神多窗口、画中画问题。

2.onConfigurationChanged 屡次回调问题

不同的厂商或者不同的用户配置,会在产生折叠时,因为状态栏或者零碎底部的虚构按键等设置,触发不同次数的 onConfigurationChanged 回调,回调下发的 screenHeightDp 数值不统一。上文曾经提到,须要针对回调参数下发的 newConfig 数据做真正的折叠判断,疏忽“伪配置变更”。

3.onNewIntent 问题

不思考折叠屏的状况下,京东小程序在多栈模式下返回时并不是真正的敞开小程序,而是压到后盾,没有触发 activity 的 finish。当用户再次关上时会触发 onNewIntent 事件,这里会进行小程序的重启。

然而遇到折叠屏,就会触发 onConfigurationChanged 和 onNewIntent 都回调的状况,通过查阅源代码和打印日志形式,咱们能够发现 onConfigurationChanged 的回调早于 onNewIntent 的。所以 onConfigurationChanged 一旦辨认到产生屏幕折叠就会重启小程序,在 onNewIntent 这里应该防止再次重启小程序。

4.webview 和 js 引擎获取屏幕宽高失真问题

在适配中咱们遇到过在某些机器上“没问题”,在其余机器上“很容易复现”的困境。在实践和实际上,客户端传递给逻辑层、视图层的尺寸数据都没问题,然而小程序体现上还是存在问题。通过粗疏的排查,发现 js 引擎上有些数据的是来自于 window 对象的宽高数据,此数据与折叠后的屏幕数据不统一,即 webview 和 js 引擎获取到的设施尺寸更新不及时,造成 rpx 计算失准。为此,咱们替换了引擎中对 window 宽高的应用形式,替换为屏幕真正的数据。

6. 修复成果展现

通过以上措施,通过验证,咱们小程序在折叠屏上的相干体验达到了比拟令人满意的成果。

内屏转外屏:

图 15 折叠屏适配后 - 内屏转外屏

外屏转内屏:

图 16 折叠屏适配后 - 外屏转内屏

外屏压后盾,再转内屏:

图 17 折叠屏适配后 - 后盾唤起

总结

折叠屏作为将来 Android 屏幕倒退的新趋势,具备很大的发展前景,做好折叠屏相干适配反对也势在必行。小程序相干适配曾经追随京东主站、小家 App、小家三星预装版等公布上线,本文是作者进行相干适配的一些心得体会,如有有余敬请见谅,欢送交换探讨。

作者:京东批发 张磊

内容起源:京东云开发者社区

退出移动版