上一章: 優酷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筆記本上,全平台打通大有可為。