共计 3819 个字符,预计需要花费 10 分钟才能阅读完成。
简介: 传统的多终端适配计划,是为大尺寸 Pad 开发一个特定的 HD 版本。然而目前反对 Android 零碎的设施类型越来越丰盛,不同类型的设施尺寸也越来越多样化,特定的 HD 版本并不能适配所有设施尺寸。App 如何在这么多尺寸的设施上,为用户提供较为统一的浏览体验?阿里巴巴娱乐技术 叮东 将分享优酷 APP 响应式的技术实现和落地办法,心愿对所有 APP 的开发同学有所启发。
Android 响应式计划
响应式的外围是拉通多终端的适配规定,开发一套界面,一个 APP 兼容多尺寸终端设备的显示,可能依据用户的行为以及设施的环境 (屏幕尺寸、屏幕方向、是否分屏等) 进行相应的页面布局以及容器尺寸的调整,为用户提供更加舒服的界面和更好的用户体验。
1 响应式 SDK
App 的每个页面反对响应式,开发成本是很高的。
响应式 SDK,就是为了解决 App 在不同尺寸设施下的适配问题,把设施的屏幕信息、容器布局规定(列数、尺寸)、业务数据二次加工等行为进行对立治理,以适应新的屏幕尺寸。
2 加载流程设计
通用的页面加载流程,通常都是从数据返回开始,数据解析实现后,进行页面布局渲染以及容器布局渲染。响应式在通用加载流程的根底上,退出了响应式状态变动告诉、响应式数据剪裁、响应式页面布局、响应式容器布局等流程。
具体加载的流程分为两种状况:
- 用户申请数据
- 屏幕尺寸发生变化
3 架构设计
优酷各个业务开发团队,应用了对立的业务架构,咱们在对立架构的根底上进行响应式适配,提供了响应式 SDK,拉通各个业务方不同页面的适配规定,确保了适配成果的一致性,同时提供了根底的响应式控件,升高业务方的接入老本,那么响应式架构具体是怎么实现的呢?
从构造上看,响应式由优酷对立架构、响应式 SDK、响应式页面布局、响应式容器布局四局部相互配合实现。在这些根底上撑持了首页、频道页、播放页、会员页、搜寻、集体核心等泛滥的业务场景。
优酷对立架构和响应式 SDK,提供响应式架构能力。
响应式页面布局、响应式容器布局,提供响应式参考实现。
4 数据二次加工
响应式并不是简略的将现有 Phone 端的业务数据,投放到 Pad、折叠屏上,单纯的进行 UI 页面适配。想要在不同尺寸设施上都能取得良好的适配成果,须要对 Phone 端的业务数据二次加工,进行数据过滤、数据映射、数据合并、数据补全等操作,能力更好的适配 Pad 和折叠屏。
响应式 SDK 只是负责把数据二次加工的协定规定定下来,具体的数据二次加工逻辑须要业务方本人实现。优酷的对立架构提供了数据切面的能力,在切面上减少数据二次解决的逻辑,实现了对立的数据处理。
数据过滤
大尺寸设施上,总会遇到一些简单的,适配不了的,也不重要的组件,这部分组件能够依据具体情况过滤解决,例如:下图中的 weex 组件,在 Pad 上间接过滤掉,不显示。
数据映射
存在一些带交互的简单组件或者 Pad 上适配成果较差的组件,能够间接映射成其余已适配的组件。例如:下图中的带视频预览的预约组件映射成一般的预约组件。
数据合并
相邻的两个组件,其中有一个组件无奈很好的适配大尺寸 Pad,能够尝试将其数据合并到其余组件内。
例如:下图中第 1 个组件宽度铺满页面宽度,在大尺寸上无奈适配,第 2 个组件通过批改列数、尺寸就能够适配。Pad 竖屏下,将第一个组件插入到第二个组件的首位,进行数据合并,依照第二个组件的进行适配,显示为 3 列 2 行,达到很好的适配成果。
数据补全
在横竖屏切换过程中,局部组件会遇到组件的数量,无奈铺满屏幕的宽度,导致呈现留白的问题。
例如:把手机上的 6 条数据,间接投放到 Pad 横屏下,就会呈现下图的留白问题:
为了解决这一类数据缺失的问题,咱们抉择的解法是服务端多下发一部分业务数据,客户端依据具体的屏幕尺寸,动静调整显示的个数,确保显示成果。
例如:下图中手机上显示 2 列 3 行,共 6 条数据,到了 Pad 竖屏上显示 3 列 2 行,共 6 条数据,到了 Pad 横屏上会补全 2 条数据,显示 4 列 2 行,共 8 条数据。
5 页面响应式
响应式状态
响应式状态是页面响应式最根底也是最重要的一个能力,像横竖屏切换、分屏模式、折叠屏折叠关上,都会导致页面的宽高发生变化,产生不同的响应式状态,页面内的内容会进行从新布局以及组件尺寸调整,以适应页面尺寸的变动,铺满屏幕,达到更好的显示成果。
横竖屏切换:
分屏模式:
折叠屏:
响应式状态治理
响应式状态与 Activity 页面的生命周期保持一致,不同页面响应式状态可能不统一。响应式 SDK 提供了 ResponsiveActivity、ResponsiveFragment 两个基类,ResponsiveActivity 对立封装了响应式的状态变动。当屏幕尺寸产生扭转时,ResponsiveActivity 和 ResponsiveFragment 会回调 onResponsiveLayout 办法,业务方接到 onResponsiveLayout 的告诉,被动遍历以后页面内的所有容器,依据响应式状态,动静批改容器的布局、布局列数、尺寸等,从新渲染以后页面。
因为优酷应用了对立框架,依据响应式状态动静批改页面内所有容器的逻辑,对立在框架外部解决,防止了业务方的批改,升高了接入老本。
/**
* 响应式状态回调
*
* @param newConfig 配置信息
* @param responsiveLayoutState 以后响应式状态
* @param responsiveLayoutStateChanged 响应式状态是否已产生扭转
*/
protectedvoidonResponsiveLayout(ConfigurationnewConfig,intresponsiveLayoutState,booleanresponsiveLayoutStateChanged) {}
获取响应式状态
响应式状态的定义,须要有一个具体计算的规定,在所有尺寸的设施上都依照对立的规定进行状态辨别,那么不同的响应式状态是如何辨别的呢?
首先定义规范手机屏幕的物理宽度为 400dp(通过大量手机设施调试采样之后取得的手机规范物理尺寸经验值),那么响应式状态的变动,由两个比例阈值决定,一个是页面物理宽度与规范物理宽度的比例阈值 1.67 倍(物理宽度 = 像素宽度÷屏幕密度),另一个是页面高度与页面宽度的比例阈值 1.25 倍。那么这两个比例阈值是如何得来的呢?
(1)1.67 倍是怎么来的呢?
在播放页的适配过程中,须要适配左右分栏的显示,咱们认为左侧播放器的宽度是规范物理宽度,那么整个页面的宽度就是规范物理宽度的 1.67 倍,这样左侧播放器有足够的空间保障视频播放的体验,右侧的也有足够的空间保障评论的显示成果。
(2)1.25 倍是怎么来的呢?
上图列举了竖屏华为 Pad 上,页面高度是页面宽度的 1.6 倍,播放器下方的视频内容操作区,显示的视频内容是足够多的。如果页面高度小于页面宽度的 1.25 倍,就会挤压视频内容操作区的高度,导致显示进去的视频内容过少,影响用户体验。
当页面物理宽度大于规范物理宽度的 1.67 倍,同时页面高度小于等于页面宽度的 1.25 倍,即为大屏状态,其余状况则为小屏状态。
不同的响应式状态
目前反对了小屏布局和大屏布局两种状态。
(1)小屏布局状态
折叠屏折叠、折叠屏分屏、Pad 竖屏:
(2)大屏布局状态
折叠屏关上、Pad 横屏:
6 容器响应式
容器响应式,次要解决在页面尺寸发生变化时,动静调整容器布局的列数以及坑位的尺寸,优酷对立架构提供了罕用的响应式容器布局:轮播布局、网格布局、横划布局、瀑布流布局。业务方能够疾速实现响应式的成果。
容器适配列数、尺寸的成果
列数适配
同一个容器,在不同的尺寸页面下,会依据页面的物理宽度动静适配,显示为不同的列数。
网络布局、横划布局、瀑布流布局都采纳这一套列数适配的规定:
响应式适配后的列数 = 以后屏幕宽度÷(规范屏幕宽度÷规范屏幕宽度下的组件列数)
响应式适配后的列数,并不能解决 Pad 横屏上局部组件列数过多,显示过密的问题,为了解决这类问题,提供了列数二次适配的能力。
如下图所示,左侧是间接依据规定算进去的 Pad 横屏下的列数 8 列,过于密集,显示成果不好,右侧是列数二次调整后,显示为 6 列。
适配成果:
控件尺寸适配
因为不同屏幕尺寸下,容器外部会动静调整显示不同的列数,导致控件的尺寸也会发生变化,那么如何适配控件尺寸的动态变化呢,响应式根底控件可能很好的解决这一类问题。
响应式根底控件,外部封装了响应式容器尺寸的适配规定,通过 ratioType 来定义不同适配规定下控件宽高的计算逻辑,业务方只须要批改最外层的布局控件,通过设置 ratioType 就能够疾速搞定宽高适配,升高业务方的适配老本。
提供了 ResponsiveConstraintLayout、ResponsiveFrameLayout、ResponsiveLinearLayout、ResponsiveRelativeLayout、ResponsiveRecyclerView 等根底响应式容器。
ratioType 的宽度计算规定示例(页面左右边距和横间距不变):
响应式控件宽度 = (以后页面的宽度 – 左右边距 – 控件之间的间距总和)÷响应式适配后的列数
总结
随着折叠屏技术的进一步倒退,折叠屏手机会越来越遍及,越来越多的 App 须要适配到折叠屏手机上,响应式能够很好的解决折叠屏的适配问题。心愿将来更多的 APP 可能适配响应式,做到一套代码,运行到不同尺寸的设施上,节约开发成本,晋升开发效力,为不同尺寸的设施带来与手机版本统一的用户体验。