写点什么

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

  • 2020-02-26
  • 本文字数:4964 字

    阅读完需:约 16 分钟

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

正如本系列第一篇文章所介绍的,Google 是从 Android 10 正式发布了对暗黑模式的支持,之前随公众理解的深色氛围一跃而上成为系统平台级能力。暗黑模式带给了我们什么呢?


  • 深色界面在专注环境下与内容有更高的契合度,更凸显内容、缓解视觉疲劳;

  • 深色界面更易营造品质感与沉浸感;

  • 深色界面更易建立填充感。

一、暗黑模式项目背景

暗黑模式作为一种系统平台能力,它打造的是整个用户使用周期的全链路视觉体验,也就是要覆盖到用户能到达的每一个角落。


这包括了分发场景,搜索场景,消费场景等复杂的页面结构,也包括二级落地页,活动页等独立页面; 还包括了弹窗,Toast,播放器等常用组件。要全面覆盖如此复杂细碎的场景,需要实现整体性的视觉呈现效果和低成本的全局平台开关。



分析完暗黑模式的影响范围,我们再来看一下我们实践的对象-优酷 APP。优酷 App 发展到今天,已经从一个单体 App,进化成了一个承载集团众多业务出口的超级 App。所以优酷 App 的页面是由十几个完整建制的内部和外部团队共同开发和维护的。


暗黑模式这种全站范围的适配将涉及到上百位设计/开发/测试同学,管理成本,沟通和协调成本,最终落地成本都非常高。


对于这种全站规格的需求,以往优酷的经验是会大量占用业务需求的开发人力,甚至会因此 delay 部分业务需求。这种开发模式是很难延续,不可接受的,本次暗黑模式的适配,我们既希望在第一时间将暗黑模式呈现给客户的,也希望能以更低的成本来完成项目需求。


这给项目方案提出了很大的挑战,但是得益于优酷之前已经实施了设计标准化体系,因此我们有信心和底气完成这些挑战。

二、暗黑模式在优酷的实践

首先,得益于优酷设计标准化体系的落地,我们已经提炼出公共资源库,构建了多层的 DesignToken 体系; 并对大部分一级页面的业务组件进行了接入。所以我们的工作就变成了两部分,一部分是已经接入设计标准化的视觉元素,这部分可以通过修改公共资源库中的 Token 定义,直接添加对暗黑模式的支持,零成本完成适配。另一部分则是扩大设计标准化体系的覆盖范围,在适配暗黑模式的同时,完成更多业务的技术架构的基础建设。


其次,我们还对于暗黑模式进行了色彩分层,静态色层是全站使用的基础色值,它直接对应着一个具体的值。它不会随着视觉模式的变化而变化。在它之上的是动态色层,动态色在不同的视觉模式下,对应不同的静态色。这是通过 Android 原生的资源加载机制完成: 即暗黑模式对应关系在暗黑资源文件中,普通模式在普通资源文件夹中。


在动态色层之上,是代码编写的色彩管理器,它在合适的时间会去获取当前的所有静态/动态色值。设计这一层有两个原因: 一个是提高性能,提前缓存一份给更上层调用,另一个是形成中间层。


众所周知,XML 资源文件的动态性是不足的。XML 资源启动即加载,加载后就是只读的。有了这一层,我们可以支持服务端动态下发色值 Token 的定义,以达成一定程度的动态性。


在色彩管理器之上,是公共的控件和组件层。有了这样的层次关系,使最终的业务设计可以通过搭建完成,完全不需要从零写起,也不需要关注设计标注的细节,开发再也不用逐个元素的调整,设计也不需要逐个像素的校对。只要在第一次纳入的时候进行一次就可以完成,大幅提高了工作效率。



静态 Token:



动态 Token:


动态色对照表



在实际的适配中,布局文件中需要注意的是要使用 Token 来设置组件属性,而在代码中则可以通过公共资源库中提供的工具方法 UIMode.isDarkMode()来读取当前是否是暗黑模式,通过 ColorConfigureManager.getInstance().getColorMap().get(token 名)来获得色值。


具体的适配工作可以看后面的相关文章。08 暗黑模式在优酷分发场景的落地、09 暗黑模式在优酷消费场景的落地 Android。


下面是暗黑模式适配的示例代码:


<?xml version="1.0" encoding="utf-8"?><com.youku.resource.widget.YKRatioLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="@dimen/resource_size_102"    android:layout_height="@dimen/resource_size_153"    android:gravity="center"    android:orientation="vertical"    app:picRatio="p2s1"    android:id="@+id/yk_item_more_layout"    android:background="@color/ykn_secondary_background">
<com.youku.resource.widget.YKTextView android:id="@+id/yk_item_more" android:layout_width="wrap_content" android:layout_height="wrap_content" style="@style/text_view_7b" android:gravity="center" android:drawableRight="@drawable/yk_title_nav_icon" android:text="更多"/></com.youku.resource.widget.YKRatioLinearLayout>

//获取下拉刷新DesignToken色值int refresBgColor = ColorConfigureManager.getInstance().getColorMap().get(YKN_DEEP_BLUE_GRADIENT_MIDDLE_POINT);//设置下拉刷新mYkClassicsHeader.setBgColor(refresBgColor);
//获取顶部导航背景资源,对应android来说都是一个命名,暗黑模式的资源单独放在night目录下int defaultImage = R.drawable.yk_top_bg;//设置顶部导航背景setPlaceHoldForeground(getResources().getDrawable(defaultImage));
//获取页面背景色int backGroundColor=ColorConfigureManager.getInstance().getColorMap().get(YKN_PRIMARY_BACKGROUND);//设置页面背景色setFragmentBackGroundColor();
复制代码


此外,我们在适配暗黑的过程中,还遇到了很多具体的问题,比如

1、低版本 Android 系统如何支持暗黑模式

虽然 Google 是在 Android 10 的版本中才默认添加了暗黑模式的切换开关,但是,在之前的系统版本中已经预埋了对暗黑资源文件夹的加载能力; 而且有一部分厂商如小米就在 Android 9 的 MIUI 定制版本中提供了切换"暗黑模式"的开关。


所以对于低版本的用户,我们也提供了适配方案。具体来说,我们是通过调用系统 API


AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO/MODE_NIGHT_YES);
复制代码


来触发模式切换的。


需要特别注意的是,使用这个函数是有一些坑的。比如,在使用它之后,如果没有在 Activity 的 manifest 文件中增加


android:configChanges=“UIMODE”


的话,在 Activity 转屏也会引起 Activity 重建。


一般的 Activity 开发逻辑可能不会考虑到这种场景,很多逻辑在这里是会引发 Bug 的。

2、如何监视暗黑模式的切换

可以通过 onConfigurationChanged 进行监听。


这里一般有两种情况:


一种是活动需要监听它,来进行手动刷新,这时需要在 manifest 文件增加上面的配置。才能够监听到系统回调。


另一种是某个控件或组件,或者我们的全局状态,可能需要独立监听,这种情况按下面的代码进行监听。


getApplication().registerComponentCallbacks(new ComponentCallbacks() {        @Override        public void onConfigurationChanged(Configuration newConfig) {        //do something        }}
复制代码

3、系统刷新和手动刷新

暗黑模式的切换必然需要重新渲染页面,这里我们分两种刷新方式:


一种是直接交给系统,系统会在切换是重建 Activity 从而引发页面重新渲染。这种适合"用户使用行为不需要记录状态"的 Native 页面,和 Weex/H5 等动态页面。缺点就是会丢失用户之前的视觉锚点。


另一种, 则是自己监听 onConfigurationChanged 事件然后手动进行有目的范围的"局部刷新"。比如优酷 App 中的播放页。请参考《极致酷黑: 优酷暗黑模式实现系列 – (9)暗黑模式在优酷消费场景的落地 Android》

4、设计体系未覆盖的老旧页面如何适配

在众多的页面中,有一些老旧的页面改造成本过高,甚至已无人维护。


如果不作任何处理的话,这些页面会因为同时使用已改造组件和未改造组件而造成不同视觉模式同时出现。为了了避免这种情况的发生,我们会在页面进入时,强制指定页面的视觉模式方法是:


getDelegate().setLocalNightMode(MODE_NIGHT_YES/MODE_NIGHT_NO);
复制代码


这个 API 的作用范围是所属的 Activity。

三、未来的展望

我们认为,设计标准化体系大大的提高了类似"暗黑模式"这种全站视觉变更项目的效率,DesignToken 的设计将开发从繁琐的视觉效果开发中解脱了出来。


优酷的暗黑模式适配在两周之内顺利完成,并且没有影响同期的产品需求。未来我们会继续深化和丰富标准化设计体系的能力,也希望这种开发方式可以在不同的 App 间变成通用的开发范式。


设计标准化体系的开发,对于公共组件池的跨应用使用,Weex/Flutter/小程序等的跨应用通投都有重要的参考意义。


作者简介


涵父,阿里文娱无线开发专家。


相关阅读


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


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


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


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


2020-02-26 10:002575

评论

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

React Fragment介绍与使用

编程江湖

React

新思科技BSIMM评估为安全团队提供“他山之石”

InfoQ_434670063458

汽车 新思科技 软件定义汽车 软件安全 BSIMM评估

做了一份前端面试复习计划,保熟~

CRMEB

如何帮助金融客户“用好云”?

阿里云云效

阿里云 运维 云原生 云平台 阿里云混合云

零代码技能平台技术实践探索

OPPO小布助手

人工智能 低代码 零代码 智能助手 对话系统

金融云原生漫谈(七)|云原生时代:从传统运维到智能运维的进阶之路

York

容器 云原生 金融科技 智能运维

Web Components 系列(二)—— 关于 Custom Elements

编程三昧

前端 组件化 2月月更

Kubernetes HPA 基于 Prometheus 自定义指标的可控弹性伸缩

张晓辉

Kubernetes 弹性 HPA

监控治理有效性评价体系

焦振清

监控治理 评价体系

读 Go 源码,可以试试这个工具

AlwaysBeta

Go golang 源码 源码解析 Go 语言

面向推理训练一体化的 MNN 工作台

阿里巴巴终端技术

端智能

如何用建木CI导入导出Redis数据

Jianmu

DevOps CI/CD Redis 数据结构

Lazada D11 体验升级技术实践

阿里巴巴终端技术

ios android 客户端开发 移动端 体验优化

一文读懂 Serverless 的起源、发展和落地实践

Serverless Devs

2月月更

sql 学习笔记

孙青

渗透测试之中间件漏洞复现

网络安全学海

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

网易传媒Go语言探索

月读

golang 开源治理

云效x钉钉:让研发工作更简单

阿里云云效

阿里云 云原生 钉钉 研发 云钉一体

恒源云(GPUSHARE)_社区大佬的论文小记(Flooding-X)

恒源云

深度学习 计算机视觉

vivo 评论中台的流量及数据隔离实践

vivo互联网技术

mongodb 中台 分布式

优秀程序员的30种思维--行为准则篇(11/100)

hackstoic

你在央视春晚抢红包,京东云却在后台玩起了“剧本杀”

脑极体

Spring Boot Serverless 实战 | Serverless 应用的监控与调试

Serverless Devs

奥运吉祥物——冰墩墩太难抢了,Python给你画一个

王小王-123

Python

关于大数据计算框架Flink内存管理的原理与实现总结 | 社区征文

张浩_house

大数据 flink 新春征文

Moviepy+OpenCV-python结合进行音视频剪辑处理 | 社区征文

老猿Python

音视频 Moviepy 数字图像处理 新春征文 OpenCV-Python

辩论这件事,其实不止奇葩说

小鲸数据

卷起来了!软件开发正在越来越快……

飞算JavaAI开发助手

aPaaS将如何改变软件行业?

华为云开发者联盟

云计算 软件 软件开发 SaaS aPaaS

推荐系统基础结构总结 | 社区征文

张浩_house

推荐系统 大数据开发 新春征文

人手一个数字人还有多远?百度吴甜做客央视《对话》

百度大脑

优酷暗黑模式(五):暗黑模式的技术实现策略_移动_阿里巴巴文娱技术_InfoQ精选文章