上一章:优酷APP响应式布局在消费场景的落地Android | 《优酷响应式布局技术全解析》第五章>>>
下一章:优酷APP响应式布局之测试方案 | 《优酷响应式布局技术全解析》第七章>>>
作者| 阿里巴巴文娱技术 金籽
一、背景
随着科技的进步,硬件设备的类型也是百花齐放,出现了各种各样的大屏设备及屏幕模式,单独APP去支撑大尺寸设备成本太高,一套代码高效支撑不同尺寸的硬件设备成为了一种趋势。在此背景下,优酷应用技术团队进行了响应式开发,播放页场景的适配重点是围绕播放器进行的,大屏设备下播放器应该如何布局、内容分发应该如何布局?下面将介绍优酷播放页在响应式适配上遇到的技术挑战及解决方案。
二、业务介绍
优酷主客消费场景即优酷App的播放页。播放页作为视频内容消费的落地页,主要提供视频播放及视频周边内容推荐,业务场景及页面内容都比较复杂。
1、 组件:即视频相关内容承载控件,包括简介,选集,周边视频,花絮视频,推荐视频等,通过这些内容让用户了解更多的视频相关的信息;
2、 半屏:包括Native、Weex、H5的半屏,通过半屏用户可以看到更多的视频相关内容,也可以承载视频互动。因为组件展示的内容还是有限,通过半屏可以更好更全地展示;
3、 Tab:通过Tab让用户在不同的内容之间切换;
4、 播放器上层:播放器交互相关功能,快进快退、下一集、清晰度、画中画等。
三、响应式与传统iPhone布局差异
如上图所示,播放页在iPhone设备上的布局比较简单,按照播放器的模式将播放页的状态分为以下几种:竖小屏模式、横全屏模式(横左全屏、横右全屏),依次对应上面的左图和右图。在竖小屏模式的时候上面是一个16:9的播放器下面是周边视频分发内容,当播放器切换到全屏模式的时候则变成一个全屏大小的播放器,整体策略简单清晰。但是iPad显示区域大大增加,如果简单的把iPhone端的布局移植过来显然是不合适的,如何有效的利用大屏设备的显示空间,提供更好的交互体验,才是响应式最终要解决的问题。
如上图所示,播放页在iPad上的布局就比较复杂了,按照播放器的模式将播放页分的状态分为以下几种:竖小屏模式、横小屏模式、横全屏模式(横左全屏、横右全屏),竖全屏模式,与iPhone端的主要区别是:
1、iPhone上小屏模式仅存在于设备方向是竖屏的时候(竖小屏模式),iPad上小屏模式既可以存在于设备方向是竖屏(竖小屏模式)也可以存在于设备方向是横屏(横小屏模式)对应的增加了一种横小屏模式;
2、iPhone上全屏模式仅存在于设备方向是横屏的时候,iPad上全屏模式既可以存在于设备方向是竖屏(竖全屏模式)也可以存在于设备方向是横屏(横全屏模式),对应的增加了一种竖全屏模式;
3、模式切换适配,由于新增加了横小平模式、竖全屏模式,那么不同模式之前的切换对应的也就增加了很多case,比如竖小屏模式切换到横小屏模式、竖全屏模式切换到横全屏模式;
4、iPad分屏特性,两个独立APP同时显示运行,举例屏幕上左边是我们优酷APP,右面可以是系统浏览器APP。
当前我们理清楚了iPhone和iPad的主要区别,同时也就明确了适配的重点,即小屏模式、竖全屏模式、模式切换、新增模式之间的切换、iPad分屏特性。
四、适配重点
1、小屏模式适配(横&竖小屏模式)
小屏模式适的配第一原则,重点关注大屏设备显示Window的宽度,根据不同设备显示Window的大小来确定播放器的大小,进而决定了整个页面的布局。优酷播放页适配的策略是如果当前大屏设备显示Window的宽度达到指定阀值,就会将整个播放页划分为两部分,左边可以看成是传统的iPhone布局(上面是一个16:9的播放器下面是周边视频分发内容),右边划归为互动区用于显示评论及播放页半屏,我们将这种布局称为分页模式。如果前大屏设备显示Window的宽度没有达到指定阀值,就是传统的iPhone布局(上面是一个16:9的播放器下面是周边视频分发内容)。
我们将整个计算逻辑抽象到一个分类中去管理,内部定义好分页模式宽度的阀值,根据这个阀值来确定当前是否处于分页模式、当前播放器的大小、右边互动区的大小,进而进行整个页面的布局
@interface UIScreen (YKRLPlayViewResponsive)
+ (CGFloat)playViewResponsiveWidth; //播放器宽度
+ (CGRect)orientationCorrectedRect; //设备尺寸
+ (CGFloat)rightExtraResponsiveWidth; //分页模式下右边区域宽度
+ (BOOL)isRightExtraMode; //是否处于分页模式下
@end
当响应式状态发生变化的时候,上面的方法(播放器尺寸、屏幕尺寸、右边区域宽度、是否分页)返回值对应的发生变化,此时根据这些变化去刷新页面布局
...
- (void)responsiveLayoutDidChange
{
//更新播放器布局
[self refreshPlayerLayout];
//更新周边视频相关布局
[self refreshPageLeftLayout];
//更新分页模式下互动区布局
[self refreshPageRightLayout];
}
...
页面布局的时候,通用的组件计算逻辑抽象成单例管理类YKDetailLayoutManager,方便复用及代码收口,后续如发生需求变化通用部分只需要在管理类中修改即可:
@interface YKDetailLayoutManager : NSObject
+(instancetype)sharedInstance;
//横滑组件,坑位正常宽度
-(CGFloat)horizontalComponentItemWidth;
//横滑组件,坑位小模式宽度
-(CGFloat)horizontalComponentItemWidthSmall;
//相关组件,坑位单列模式宽度
-(CGFloat)aboutComponentSingleItemWidth;
//相关组件,坑位多列模式宽度
-(CGFloat)aboutComponentDoubleItemWidth;
//选集组件,坑位宽度
-(CGFloat)episodeComponentSeriesItemWidth;
...
@end
小屏模式下播放页半屏适配,播放页半屏是播放页特有的一种展示,在iPhone上半屏处于播放器的下方并撑满屏幕宽度,响应式下最大的变更是如果当前处于分页模式下,播放页半屏将展示在屏幕的右侧区域上面,适配重点就是收口半屏Frame,当半屏页面初始化或者响应式状态变化的时候刷新半屏布局。
...
- (CGRect)halfViewFrame
{
case1:当前是分页模式,返回右边互动区的frame
case2:当前不是分页模式,返回播放器下面周边视频对应的frame
}
...
...
- (void)responsiveLayoutDidChange
{
//获取半屏的frame
CGRect halfFrame = [self halfViewFrame];
//根据获得的半屏frame,刷新半屏布局
[self refreshHalfViewWithFrame:halfFrame];
}
...
2、竖全屏模式适配
在iPhone上优酷播放器上层之前针对竖版视频推出过轻量级的竖全屏模式,只有竖版视频才存在这种状态,响应式布局在此基础上将这种模式推广到全部视频上,所以适配起来比较顺畅。
3、模式切换适配
在iPad上模式切换变得比较复杂,新增了一些iPone上并不存在的case,比如竖小屏模式切换到横小屏模式、横小屏模式切换到竖小屏模式、横全屏模式换到竖全屏模式、竖全屏模式切换到横全屏模式。我们的适配原则是:
1) 遵守播放器上层架构开发标准;
2) 对播放器上层架构侵入较小;
3) 代码聚合解耦。
最终方案是抽象出一个轻量级别的中间件来完成模式的切换,对原有架构实现无侵入插入,内部基本原理就是监听响应式的状态变化,根据当前的设备屏幕方向及当前播放页的模式,来动态改变播放页的模式并且刷新页面布局:
...
- (void)responsiveLayoutDidChange
{
case1:
当前设备是竖屏方向,当前模式是横左或横右全屏模式 , 主动切换到竖全屏模式
case2:
当前设备是横左方向,当前模式是竖全屏模式, 主动切换到横左全屏模式
case3:
当前设备是横右方向,当前模式是竖全屏模式, 主动切换到横右全屏模式
case4:
横小屏模式和竖小屏模式之间切换, 要强制刷一下
}
...
4、分屏特性适配
iPad分屏特性如何处理呢?其实分屏只是动态的改变了显示Window的宽度,只要我们严格遵循原则按照Window的宽度去适配,上面的布局方式将会完美的应用于分屏特性,我们并不需要去做更多的工作来适配分屏。效果如下:
五、总结
1、响应式适配的时候尽量避免到处打patch,到处 if else 的去修改UI布局,原则上按照父 view大小来布局子view,也可以使用自动布局等方案进行适配;
2、尽最大努力实现同样代码,在iPhone和iPad上都能完美运行;
3、充分梳理好当前的技术架构,提炼出适合自己的技术方案,要充分考虑可扩展性、可维护性、性能等诸多前置条件;
4、相信在不久的将来,移动端APP将会流畅的运行在MAC笔记本上,全平台打通大有可为。