写点什么

优酷暗黑模式(九):消费场景落地(Android)

  • 2020-02-28
  • 本文字数:3324 字

    阅读完需:约 11 分钟

优酷暗黑模式(九):消费场景落地(Android)

优酷播放页的暗黑模式是在设计标准化的基础上,参考了 DesignToken 来实现设计的。之前播放页已经接入了组件标准化,为暗黑模式的适配提供了很大的便利。

一、播放页业务介绍

播放页作为用户视频消费场景的落地页,主要提供包括视频播放、内容介绍、互动、推荐、花絮、周边、推荐等。业务类别及页面元素都比较复杂,页面类别有:剧集、电影、综艺、少儿、体育、新知等;其元素主要有:组件、半屏、tab 等。


常见的几种页面类别及元素如下图所示。


二、播放页场景特殊性

相对于其它场景,播放场景有其特殊性。


首先,用户在观看视频的时候切换暗黑模式不能打断用户的操作(如定时切换),需要实现无缝切换以达到良好的播放体验,所以在切换模式的选择上和其它场景会有区别。


其次,播放页组件有 30 多个,同时还会有半屏(包括 native 及 H5),弹框,及少儿、评分、评论等其他业务团队页面的承接,UI 适配涉及改动点比较广。


最后,播放页原先已经具备沉浸式观影模式,在某些剧集上会生效,它也属于氛围的一种,需要做好隔离,避免与暗黑模式相互影响。

三、页面适配架构


播放页架构的最底层是优酷的统一渲染架构以及标准化组件。如前文所述,因为播放页有沉浸式观影模式,我们做了一层资源管理层,用于隔离沉浸式模式和暗黑模式,同时可以更好的统一管理播放页的资源,便于维护。最上层则为要适配的页面相关组件、半屏等。

四、页面适配方案

1、资源适配

资源适配主要有颜色适配和资源适配,两者都是采用标准化的方式来适配,适配方式可以参考《暗黑模式的技术支撑(Android)》。

2、刷新模式对比

2.1 Android 系统的两种刷新模式

Android 10 系统对于暗黑模式与正常模式的刷新采用两种刷新方式:


(1) recreate 方式:该方式下正常模式与暗黑模式切换时,会对整个 Activity 进行 recreate,绘制时根据模式,获取不同的颜色进行绘制,


(2) uimode 方式:即业务根据需要自行刷新模式,正常和暗黑模式切换时并不会 recreate 整个 Activity,需要业务自己去刷新要适配的页面和组件。这种模式需要在 AndroidManifest 的 configChanges 配置 uimode,防止进入 recreate 模式。

2.2 两种模式对比

recreate 方式:


  • 优点:适配简单,在适配时直接修改颜色为 DesignToken 动态色,资源放置在 drawable-night 下即可。当系统切换模式,recreate 整个 Activity 的时候自动获取颜色绘制。

  • 缺点:模式切换之后对于用户的体验不好,每次切换以后都会重新加载,用户之前的观看及操作会丢失,需要重新加载。


uimode 方式:


  • 优点:用户体验比较好,模式切换的时候可以无感知切换,不影响用户观看及之前的操作;

  • 缺点:适配刷新比较复杂,不会 recreate Activity 要主动去刷新,需要考虑弹框,半屏,及前后台切换影响。颜色适配及资源适配都需要手动获取设置。


对于两种刷新模式的选择,需要根据业务场景来选择适合哪种模式。对于优酷的分发页面,页面重建对于用户操作影响并不大,可以采用 recreate 模式,适配起来不用考虑主动触发刷新。

3、播放页具体刷新方案

从用户体验的角度出发,用户在观看视频的时候,并不想在任何时候被打断,最终采用 uimode 的方式来刷新整个页面,做到无感知刷新,防止 recreate 页面之后播放重新开始。这种情况下就需要页面主动去触发刷新。


播放页有 30 个多个组件,加上半屏、弹窗如果每个单独去刷新适配工作量太大,且像选集有很多分季 tab 及分集,单独去做刷新显然不太可能,所以需要比较通用的方式去刷新,做到一次调用整体刷新。


最终采用的方案是,将刷新分为三类:最底层整体页面与 tab、组件、半屏及弹窗,具体适配方案如下:


刷新适配时,通知刷新部分及资源选取(上面提到的资源适配)采用系统提供的方式,后面刷新过程中颜色处理还是按照组件标准化的统一规则(上面提到的颜色适配)来进行刷新适配。

3.1 触发刷新(系统的刷新方案)

采用系统提供的 uimode 模式,在 manifest 配置 uimode 模式防止 recreate activity


<activity    android:name="com.youku.ui.activity.DetailActivity"    android:configChanges="uiMode"Copy    监听onConfigurationChanged()来判断是否暗黑模式切换:@Overridepublic void onConfigurationChanged(Configuration newConfig) {             //普通与暗黑模式切换       int  currentNightMode = newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK;       if (mCurrentUIMode != currentNightMode) {        //通知刷新        .......    }}
复制代码


具体流程:


3.2 tab 与背景刷新

tab 和背景整体可以看作是一个页面承载底层,统一刷新来设置整个 tab 背景及页面最底层背景。刷新过程中注意 tab 的锚定,比如当前在第二个 tab,刷新之后也要锚定到第二个 tab。

3.3 组件刷新

每个组件可以看作是 RecyclerView 的一个子 View,所以刷新采用 Adapter 的 notifyDataSetChanged 方式。获取到整个加载组件的列表即 componentList,然后对每个 Component 的 Adapter 通过 notifyDataSetChanged 去调用整个组件的刷新,这个时候页面数据已经在本地存在,相当于只是刷新 View 样式。


这个过程中,遇到过一个问题就是播放页数据刷新的时候做了多次刷新的保护(下图中 check 组件是否可以刷新部分),所以如果不是数据的变化,则不会去执行刷新,要解决这个问题需要设置一个新的刷新状态,由于组件过多,只能采用统一处理的方式,在组件数据的统一父类中设置状态改变的方法;当判断出组件已加载,且 UI 模式已切换后,则设置组件可以刷新,在组件刷新时可以很方便拿到这个状态,判断该状态去刷新。


简单刷新流程概括如下:




后台切换刷新,不会影响观看

3.4 半屏及弹窗刷新

半屏及弹窗的刷新比较复杂,播放页整个半屏采用 View 打开的方式,且半屏对应也有很多种样式。比如多种展示 View,多种不同背景,外部页面(如评论部分,承接在播放页,背景需要播放页控制)透明背景等;同时也要考虑用户当前打开了半屏,然后退到后台再切换模式的情况。


在半屏适配采用的方案是:每次半屏的打开需要记录下来,刷新时判断容器当前是否正在打开,半屏的背景用同一个 tag 标记,当接收到刷新通知之后,判断当前打开的半屏,根据 tag 去刷新背景,这样就不用再每个半屏去处理,直接通过 tag 统一刷新。对于特殊半屏的刷新,实现调用刷新方法做特殊 Viewiew 的刷新处理,调用该方法进行各自 View 的刷新,具体流程如下:




半屏刷新,不会关闭半屏,直接切换

3.5 与沉浸式模式隔离

在适配暗黑模式的过程中,沉浸式模式与其会互相影响,需要做到相互隔离。下面是沉浸式的一个样式,该页面可以给用户更好的观影体验,背景采用高斯模糊图的方式,可以开关控制。


从页面可以看出,其效果也是对于不同样式的处理,但是沉浸式是运营控制开关投放,背景是一层高斯模糊,对于背景,字体,颜色的处理还是不同,所以在适配的过程中需要做一层颜色及资源管理层(架构图中的颜色资源管理层),来区分沉浸式氛围及暗黑的处理。通过不同的开关控制背景处理及加载不同的资源、颜色。后期沉浸式将会接入全局统一氛围配置,做到自动下发氛围相关样式,减少适配工作。


五、总结

1、根据自身的业务场景选择适合业务的刷新方式,比如播放页不能打断用户操作及观看,采用 uimode 方式;


2、模块比较多的情况下,尽量考虑相互关联的模块一起去处理刷新,提高适配效率;


3、同一类 View 比如半屏背景,或者 RecyclerView 采用统一的管理方式,做到一次调用,全部刷新;


4、有其他 UI 样式相关的处理比如换肤,氛围,要考虑相互之间的影响;


5、对于使用 uimode 模式,要考虑用户退出后台模式修改的情况,以及用户设定了具体时间进入暗黑模式的情况。当重新回到 App,做到无缝刷新;尤其在打开弹窗,半屏,tab 锚定的时候,具体效果可看下面适配效果。

六、适配效果


作者简介


吉欧,阿里文娱无线高级开发工程师。


相关阅读


优酷暗黑模式(一):是什么、为什么、如何落地?


优酷暗黑模式(二):如何建立设计语言标准化管理体系


优酷暗黑模式(三):暗黑模式设计指南


优酷暗黑模式(四):设计标准化的技术实现


优酷暗黑模式(五):暗黑模式的技术实现策略


优酷暗黑模式(六):暗黑模式的技术支撑 iOS


优酷暗黑模式(七):暗黑模式的技术支撑 Weex & H5


优酷暗黑模式(八):分发场景落地(Android & iOS)


2020-02-28 10:001908

评论

发布
暂无评论
发现更多内容

安卓开发详解!Flutter全方位深入探索,吊打面试官系列!

欢喜学安卓

android 程序员 面试 移动开发

Dubbo 版 Swagger 来啦!Dubbo-Api-Docs 发布

阿里巴巴云原生

Java 云原生 dubbo 大前端 中间件

【设计模式】断路器模式

soolaugust

设计模式 28天写作

再谈跨界 互联网+的建筑行业

张老蔫

28天写作

Spring中@Import的作用

张健

波场链智能合约软件开发|波场链智能合约APP系统开发

系统开发

专科出身Java开发,2年进入苏宁,5年跳槽阿里,我晋升这么快的秘诀是什么?

Java架构追梦

Java 阿里巴巴 面试 架构师 成长路线

阿里开发7年大牛:闭关60天学懂NDK+Flutter,大厂面试题汇总

欢喜学安卓

android 程序员 面试 移动开发

求职阿里Java 技术岗位的经历,三轮技术面+HR面,面试也不过如此

Java架构之路

Java 程序员 架构 面试 编程语言

WireMock 使用

hungxy

测试 WireMock

连续三年蝉联第一,Flink 荣膺全球最活跃的 Apache 开源项目

Apache Flink

Apache flink

真是太刺激了!美团CTO五轮面试,Java岗高级工程师一二三四五面面经(已拿到offer)

Java架构之路

Java 程序员 架构 面试 编程语言

华为云张昆:支持全场景全业务,GaussDB加速企业数字化转型

华为云开发者联盟

数据库

SpringCloud 从入门到精通 08--- Eureka集群

Felix

第九周作业

dll

sync.singleflight 到底怎么用才对?

cyningsun

并发 Concurrency singleflight Cache Miss Go 语言

Alluxio Day 2021 线上直播

腾讯云大数据

大数据

SpringCloud 从入门到精通 09--- 支付服务集群

Felix

week8-homework

J

毕业三年,从小公司到大厂,先后四面阿里、小米、美团等,终于收到offer!

Java架构之路

Java 程序员 架构 面试 编程语言

量化自动交易系统开发,量化炒币

薇電13242772558

数字货币 策略模式

CSS12 - 清除浮动

Mr.Cactus

html/css

区块链即时通讯系统开发方案,IM聊天社交软件开发

v16629866266

即构推出低延迟直播产品L3,可将直播延迟降到1s

ZEGO即构

从根上理解高性能、高并发(四):深入操作系统,彻底理解同步与异步

JackJiang

网络编程 高并发 高性能 即时通讯

面向对象之魔术方法· 第1篇《__init__方法,__new__方法》

清菡软件测试

测试

用技术的方式,在UI设计稿中设置随机码,保证高清

行者AI

Python

程序员的五年:双非学历,两年进入苏宁,五年跳槽到阿里,建议收藏!

996小迁

Java 架构 面试 JVM Spring全家桶

重学JS | 异步编程 Promise

梁龙先森

大前端 编程语言 28天写作

Mobileye的创新科技与方案将助力自动驾驶汽车畅行世界、惠及大众

E科讯

对于我们程序员来说,基本面是什么呢?

Java架构师迁哥

优酷暗黑模式(九):消费场景落地(Android)_移动_阿里巴巴文娱技术_InfoQ精选文章