10 月 23 - 25 日,QCon 上海站即将召开,现在大会已开始正式报名,可以享受 8 折优惠 了解详情
写点什么

优酷暗黑模式(九):消费场景落地(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:002190

评论

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

DeFi去中心化平台源码开发|智能合约系统搭建

量化系统19942438797

🏆「作者推荐」【JVM 性能调优】JVM分析与调优技巧分析(原理篇)

码界西柚

JVM JVm虚拟机 8月日更

前端之算法(一)

Augus

数据结构与算法 8月日更

TCP 三次握手

W🌥

计算机网络 TCP/IP 8月日更

企业不可忽视的三大关键时刻

石云升

管理经验 关键时刻 体验设计 8月日更

手把手 Golang 实现静态图像与视频流人脸识别

声网

音视频 人脸识别

从新手村出来,我在 Apache APISIX 社区发出了第一个 PR

API7.ai 技术团队

开源 后端 API网关 APISIX

记一次PHP渗透测试实战教程

网络安全学海

php 网络安全 信息安全 渗透测试 安全漏洞

LeetCode题解:80. 删除有序数组中的重复项 II,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

企业数字化转型第一步,云服务器的部署以及搭建

九河云安全

舍弃Kong和Nginx,Apache APISIX 在趣链科技 BaaS 平台的落地实践

API7.ai 技术团队

nginx 开源 网关 kong APISIX

使用FL studio中文版进行音乐合并和剪切

懒得勤快

RESTful API

escray

学习 极客时间 如何落地业务建模 8月日更

「独立思考」的背后是一个残酷的世界

非著名程序员

提升认知 个人提升 独立思考 8月日更

新药开发瓶颈问题或将被打破,北鲲云超算平台开启药物研发“加速度”

北鲲云

基于时间和窗口的算子(六)

Databri_AI

flink 窗口函数 算子

绝了!阿里甩出“源码阅读指南”,原来源码才是最经典的学习范例

Java 编程 架构 面试 程序人生

图谱可视化|手把手教你采集明星人物关系并进行图谱展示

Python研究者

知识图谱 8月日更

Karmada: 云原生多云容器编排平台

华为云原生团队

开源 容器 k8s多集群管理 多云管理平台 多云

聊聊 PC 端自动化最佳方案 - WinAppDriver

星安果

Python 自动化 WinAppDriver

一文带你了解大厂亿级并发下高性能服务器是如何实现的!

Linux服务器开发

事件驱动 多进程 Linux服务器开发 IO多路复用 高性能服务器

CSS 文档中定位指南:static、relative、absolute、fixed、sticky

devpoint

CSS 8月日更

网络攻防学习笔记 Day102

穿过生命散发芬芳

态势感知 网络攻防 8月日更

从安卓转到Java开发,我吃透了这份pdf,终于4面拿下美团offer

Java~~~

Java spring 面试 微服务 JVM

波场DAPP钱包开发|波场DAPP特点

Geek_23f0c3

钱包系统开发 DAPP智能合约交易系统开发 波场DAPP 波场钱包

用区块链加强知识产权保护

CECBC

趁着课余时间学点Python(十)面向对象的理解(前奏)

ベ布小禅

8月日更

fil矿机怎么购买?fil矿机在哪买?

fil矿机怎么购买 fil矿机在哪买

程序员投入时间和精力实现财富增长之道,这可能会伴随你程序员整个生涯(请不要连续点赞)

孙叫兽

程序员 赚钱 教程 引航计划 签约计划第二季

ipfs矿机挖币哪家最好?ipfs矿机公司实力排行如何?

ipfs矿机挖币哪家最好 ipfs矿机公司实力排行如何

区块链难懂?人民日报评论员讲给你听

CECBC

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