写点什么

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

评论

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

海纳 “千川”:得物多场景统一推荐平台

得物技术

加速44%!RT-DETR量化无损压缩优秀实战

飞桨PaddlePaddle

人工智能 百度 paddle

喜报|瑞云科技荣获“年度汽车数字化营销供应商”奖

3DCAT实时渲染

云仿真 汽车三维可视化 汽车虚拟仿真

ByteHouse+Apache Airflow:高效简化数据管理流程

字节跳动数据平台

airflow 数据管理 bytehouse

JS中, Set为什么是带键的集合?

林十二XII

前端

MegEngine 使用小技巧:如何做 MegCC 的模型性能评测

MegEngineBot

深度学习 开源 性能测试 编译器 MegEngine

手势识别技术及其应用

数据堂

软件测试|抓包工具Charles--出现unknown怎么解决?

霍格沃兹测试开发学社

建设数字工厂:生产物料齐套检查的实现方法

华为云开发者联盟

华为云 华为云开发者联盟 企业号 6 月 PK 榜

生产环境可用的 Seata-go 1.2.0 来啦!!!

SOFAStack

Java seata 版本发布 Seata框架 Seata-go

智达方通EPM 发布5.0版本,持续赋能企业数智化管理

智达方通

EPM 智达方通 全面预算管理 智达方通EPM 企业绩效管理系统

Seata Saga 模式快速入门和最佳实践

SOFAStack

分布式 云原生 开发 seata Seata框架

2023-06-14:我们从二叉树的根节点 root 开始进行深度优先搜索。 在遍历中的每个节点处,我们输出 D 条短划线(其中 D 是该节点的深度) 然后输出该节点的值。(如果节点的深度为 D,则其

福大大架构师每日一题

Go 算法 rust 福大大架构师每日一题

风口上的AIGC,技术岗动不动年薪百万,甚至重金难求?

引迈信息

人工智能 低代码 AIGC ChatGPT

GitHub 2800颗星,支持GPT/Transformer,字节跳动这个开源项目是怎么来的?

字节跳动技术范儿

机器学习 nlp

架构模块2作业

sandywrh

当 GraphQL 遇上图数据库,便有了更方便查询数据的方式

NebulaGraph

图数据库 graphql

精打细算:OptaPlanner如何帮助您找到最佳优惠券组合

PeterOne

算法 运筹优化 6 月 优质更文活动

华为手环、耳机等礼品!等你拿~快来参与CodeArtsBuild实践体验!

云计算 华为 华为云

联盟送福利:云上掘金,开启你收入的第二增长曲线

华为云开发者联盟

云计算 华为云 华为云开发者联盟 企业号 6 月 PK 榜

用Optaplanner实现云资源优化:建模详解

PeterOne

算法 后端 运筹优化 6 月 优质更文活动

Generative AI 新世界:文本生成领域论文解读

亚马逊云科技 (Amazon Web Services)

机器学习

2种GaussDB(DWS)查看作业运行信息方式

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 企业号 6 月 PK 榜

Spring Security6 全新写法,大变样!

江南一点雨

Java springboot springsecurity

WMS 库存系统设计

红袖添香

系统设计 供应链物流 WMS系统 库存系统

Acrobat Pro DC 2023 for Mac(PDF编辑器) 中文最新

背包客

macos Mac软件 pdf编辑工具 Acrobat DC 2023 Acrobat DC

手势识别技术的挑战和未来发展

数据堂

ubuntu服务器安装图形化界面总结

Studying_swz

6 月 优质更文活动

C语言编程—命令行参数

芯动大师

C语言 命令行参数解析 6 月 优质更文活动

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