优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章

上一章:优酷APP响应式布局技术概述 | 《优酷响应式布局技术全解析》第一章>>>
下一章:优酷APP响应式布局技术之iOS篇 | 《优酷响应式布局技术全解析》第三章>>>

作者| 阿里巴巴文娱技术 叮东

一、背景

传统的多终端适配方案,是为大尺寸Pad开发一个特定的HD版本。但是目前支持Android系统的设备类型越来越丰富,不同类型的设备尺寸也越来越多样化,特定的HD版本并不能解决所有设备尺寸上的适配问题,同时开发团队也难以保持多端相同的开发人力投入,App如何在这么多尺寸的设备上,为用户提供较为一致的浏览体验,是多终端适配的难点。

优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章

为了解决多终端适配的问题,优酷应用中心技术团队开启了响应式的技术预研,在8月份版本中,全面上线了响应式。经过实际的数据对比,效果达到预期。本文将分享优酷响应式的技术实现和落地方法,希望对所有APP的开发同学有所启发。

二、Android响应式方案

响应式的核心是拉通多终端的适配规则,开发一套界面,一个APP兼容多尺寸终端设备的显示,能够根据用户的行为以及设备的环境(屏幕尺寸、屏幕方向、是否分屏等)进行相应的页面布局以及容器尺寸的调整,为用户提供更加舒适的界面和更好的用户体验。

1、响应式SDK

App的每个页面支持响应式,开发成本是很高的。
响应式SDK,就是为了解决App在不同尺寸设备下的适配问题,把设备的屏幕信息、容器布局规则(列数、尺寸)、业务数据二次加工等行为进行统一管理,以适应新的屏幕尺寸。

优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章

2、加载流程设计

优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章

通用的页面加载流程,通常都是从数据返回开始,数据解析完成后,进行页面布局渲染以及容器布局渲染。响应式在通用加载流程的基础上,加入了响应式状态变化通知、响应式数据剪裁、响应式页面布局、响应式容器布局等流程。
具体加载的流程分为两种情况:
1)用户请求数据;
2)屏幕尺寸发生变化;

3、架构设计

优酷各个业务开发团队,使用了统一的业务架构,我们在统一架构的基础上进行响应式适配,提供了响应式SDK,拉通各个业务方不同页面的适配规则,确保了适配效果的一致性,同时提供了基础的响应式控件,降低业务方的接入成本,那么响应式架构具体是怎么实现的呢?

优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章

从结构上看,响应式由优酷统一架构、响应式SDK、响应式页面布局、响应式容器布局四部分相互配合完成。在这些基础上支撑了首页、频道页、播放页、会员页、搜索、个人中心等众多的业务场景。
优酷统一架构和响应式SDK,提供响应式架构能力。
响应式页面布局、响应式容器布局,提供响应式参考实现。

4、数据二次加工

响应式并不是简单的将现有Phone端的业务数据,投放到Pad、折叠屏上,单纯的进行UI页面适配。想要在不同尺寸设备上都能获得良好的适配效果,需要对Phone端的业务数据二次加工,进行数据过滤、数据映射、数据合并、数据补全等操作,才能更好的适配Pad和折叠屏。
响应式SDK只是负责把数据二次加工的协议规则定下来,具体的数据二次加工逻辑需要业务方自己实现。优酷的统一架构提供了数据切面的能力,在切面上增加数据二次处理的逻辑,实现了统一的数据处理。

4.1、数据过滤

大尺寸设备上,总会遇到一些复杂的,适配不了的,也不重要的组件,这部分组件可以根据具体情况过滤处理,例如:下图中的weex组件,在Pad上直接过滤掉,不显示。

优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章

4.2、数据映射

存在一些带交互的复杂组件或者Pad上适配效果较差的组件,可以直接映射成其他已适配的组件。例如:下图中的带视频预览的预约组件映射成普通的预约组件。

优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章

4.3、数据合并

相邻的两个组件,其中有一个组件无法很好的适配大尺寸Pad,可以尝试将其数据合并到其他组件内。
例如:下图中第1个组件宽度铺满页面宽度,在大尺寸上无法适配,第2个组件通过修改列数、尺寸就可以适配。Pad竖屏下,将第一个组件插入到第二个组件的首位,进行数据合并,按照第二个组件的进行适配,显示为3列2行,达到很好的适配效果。

优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章

4.4、数据补全

在横竖屏切换过程中,部分组件会遇到组件的数量,无法铺满屏幕的宽度,导致出现留白的问题。
例如:把手机上的6条数据,直接投放到Pad横屏下,就会出现下图的留白问题。

优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章

为了解决这一类数据缺失的问题,我们选择的解法是服务端多下发一部分业务数据,客户端根据具体的屏幕尺寸,动态调整显示的个数,确保显示效果。
例如:下图中手机上显示2列3行,共6条数据,到了Pad竖屏上显示3列2行,共6条数据,到了Pad横屏上会补全2条数据,显示4列2行,共8条数据。

5、页面响应式

5.1、响应式状态

响应式状态是页面响应式最基础也是最重要的一个能力,像横竖屏切换、分屏模式、折叠屏折叠打开,都会导致页面的宽高发生变化,产生不同的响应式状态,页面内的内容会进行重新布局以及组件尺寸调整,以适应页面尺寸的变化,铺满屏幕,达到更好的显示效果。

横竖屏切换

优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章

分屏模式

优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章

折叠屏
优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章
优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章

5.2、响应式状态管理

响应式状态与Activity页面的生命周期保持一致,不同页面响应式状态可能不一致。响应式SDK提供了ResponsiveActivity、ResponsiveFragment两个基类,ResponsiveActivity统一封装了响应式的状态变化。当屏幕尺寸发生改变时,ResponsiveActivity和ResponsiveFragment会回调onResponsiveLayout方法,业务方接到onResponsiveLayout的通知,主动遍历当前页面内的所有容器,根据响应式状态,动态修改容器的布局、布局列数、尺寸等,重新渲染当前页面。
由于优酷使用了统一框架,根据响应式状态动态修改页面内所有容器的逻辑,统一在框架内部处理,避免了业务方的修改,降低了接入成本。

    /**
     * 响应式状态回调
     *
     * @param newConfig                    配置信息
     * @param responsiveLayoutState        当前响应式状态
     * @param responsiveLayoutStateChanged 响应式状态是否已发生改变
     */
    protected void onResponsiveLayout(Configuration newConfig, int responsiveLayoutState, boolean responsiveLayoutStateChanged) {

    }

5.3、获取响应式状态

响应式状态的定义,需要有一个具体计算的规则,在所有尺寸的设备上都按照统一的规则进行状态区分,那么不同的响应式状态是如何区分的呢?
首先定义标准手机屏幕的物理宽度为400dp(经过大量手机设备调试采样之后获得的手机标准物理尺寸经验值),那么响应式状态的变化,由两个比例阈值决定,一个是页面物理宽度与标准物理宽度的比例阈值1.67倍(物理宽度 = 像素宽度 ➗ 屏幕密度),另一个是页面高度与页面宽度的比例阈值1.25倍。那么这两个比例阈值是如何得来的呢?

1.67倍是怎么来的呢?

优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章

在播放页的适配过程中,需要适配左右分栏的显示,我们认为左侧播放器的宽度是标准物理宽度,那么整个页面的宽度就是标准物理宽度的1.67倍,这样左侧播放器有足够的空间保障视频播放的体验,右侧的也有足够的空间保障评论的显示效果。

1.25倍是怎么来的呢?

优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章

上图列举了竖屏华为Pad上,页面高度是页面宽度的1.6倍,播放器下方的视频内容操作区,显示的视频内容是足够多的。如果页面高度小于页面宽度的1.25倍,就会挤压视频内容操作区的高度,导致显示出来的视频内容过少,影响用户体验。
当页面物理宽度大于标准物理宽度的1.67倍,同时页面高度小于等于页面宽度的1.25倍,即为大屏状态,其他情况则为小屏状态;

5.4、不同的响应式状态

目前支持了小屏布局和大屏布局两种状态。

小屏布局状态
优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章
优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章

大屏布局状态
优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章
优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章

6、容器响应式

容器响应式,主要解决在页面尺寸发生变化时,动态调整容器布局的列数以及坑位的尺寸,优酷统一架构提供了常用的响应式容器布局:轮播布局、网格布局、横划布局、瀑布流布局。业务方可以快速实现响应式的效果。

6.1、容器适配列数、尺寸的效果

优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章

6.2、列数适配

同一个容器,在不同的尺寸页面下,会根据页面的物理宽度动态适配,显示为不同的列数。
网络布局、横划布局、瀑布流布局都采用这一套列数适配的规则
响应式适配后的列数 = 当前屏幕宽度 ➗ (标准屏幕宽度 ➗ 标准屏幕宽度下的组件列数 )
响应式适配后的列数,并不能解决Pad横屏上部分组件列数过多,显示过密的问题,为了解决这类问题,提供了列数二次适配的能力。
如下图所示,左侧是直接根据规则算出来的Pad横屏下的列数8列,过于密集,显示效果不好,右侧是列数二次调整后,显示为6列。

优酷APP响应式布局技术之Android篇 | 《优酷响应式布局技术全解析》第二章

6.3、控件尺寸适配

由于不同屏幕尺寸下,容器内部会动态调整显示不同的列数,导致控件的尺寸也会发生变化,那么如何适配控件尺寸的动态变化呢,响应式基础控件能够很好的解决这一类问题。
响应式基础控件,内部封装了响应式容器尺寸的适配规则,通过ratioType来定义不同适配规则下控件宽高的计算逻辑,业务方只需要修改最外层的布局控件,通过设置ratioType就可以快速搞定宽高适配,降低业务方的适配成本。
提供了ResponsiveConstraintLayout、ResponsiveFrameLayout、ResponsiveLinearLayout、ResponsiveRelativeLayout、ResponsiveRecyclerView等基础响应式容器

ratioType的宽度计算规则示例(页面左右边距和横间距不变):
响应式控件宽度 = (当前页面的宽度 - 左右边距 - 控件之间的间距总和) ➗ 响应式适配后的列数;

三、效果演示

1、折叠屏

折叠屏.mov

2、Pad
Pad.mov

四、总结

随着折叠屏技术的进一步发展,折叠屏手机会越来越普及,越来越多的App需要适配到折叠屏手机上,响应式可以很好的解决折叠屏的适配问题。 希望未来更多的APP能够适配响应式,做到一套代码,运行到不同尺寸的设备上,节约开发成本,提升开发效能,为不同尺寸的设备带来与手机版本一致的用户体验。

上一篇:优酷APP响应式布局技术概述 | 《优酷响应式布局技术全解析》第一章


下一篇:从代码到上线, 云端Docker化持续交付实践