【AICon】探索RAG 技术在实际应用中遇到的挑战及应对策略!AICon精华内容已上线73%>>> 了解详情
写点什么

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

  • 2020-02-27
  • 本文字数:4502 字

    阅读完需:约 15 分钟

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

一、背景介绍

随着 Android 10 与 iOS 13 先后支持暗黑模式,优酷客户端在完成了架构统一和组件标准化的工作之后,分发场景的复杂业务可以基于统一的技术方案进行暗黑模式的适配。

二、业务介绍

由于优酷业务分发场景业务复杂,承载页面众多(二十多种),在落地暗黑模式前,我们对优酷分发场景的业务进行了梳理,大致可以分为三类:


第一类是固定入口的页面,比如首页、频道、Feed 流、二级页,它们承接了分发场景的大部分业务,拥有样式丰富的组件库,它们的共性非常高。



第二类是独立业务方开发的二级页,这些二级页由垂直业务团队维护。由于优酷客户端已完成架构统一和组件标准化的工作,各个业务团队适配暗黑模式都是基于同一套技术方案,适配就变成了一个标准化的工作。业务团队只需按统一的方式适配即可,极大提高了开发效率。



第三类是一些历史遗留的一些老页面,这些页面没有固定的入口,入口分散在各个页面和各个组件, 适配暗黑模式成本相对较高。


这样的页面可以有两种处理方式:


  1. 流量小,非核心的分发场景,面临下线的业务不进行暗黑模式的适配。

  2. 有业务价值的页面进行迁移或合并,统一用新版的二级页承载。



三、暗黑适配

页面展现分几种状态:转场态, 加载态(Loading), 展现态,异常态。暗黑模式适配的主要工作是适配页面的展现态;转场态和加载态的生命周期虽然很短,但是不能忽略,否则很容易出现亮色-暗色页面状态的切换,会破坏整体的沉浸式浏览体验,异常态也是因为类似原因不能忽略。


1、页面级别

1) 顶部/底部导航/容器

顶部导航支持换背景色;底部导航支持换图片资源、文字颜色、背景颜色;容器支持背景色。



Android 示例代码


//获取下拉刷新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();
复制代码


iOS 示例代码


/// 暗黑变化回调/// @param manager 当前的主题管理对象/// @param identifier 当前主题的标志/// @param theme 当前主题对象- (void)ykn_themeDidChangeByManager:(YKNThemeManager *)manager identifier:(__kindof NSObject<NSCopying> *)identifier theme:(__kindof NSObject *)theme {    [super ykn_themeDidChangeByManager:manager identifier:identifier theme:theme];
// 顶部渐变色:深蓝渐变顶部Token CGColorRef topCGColor = UIColor.ykn_deepBlueGradientTopPoint.CGColor; // 底部渐变色:深蓝渐变底部Token CGColorRef midCGColor = UIColor.ykn_deepBlueGradientMiddlePoint.CGColor; if (topCGColor && midCGColor) { _gradientLayer.colors = @[(__bridge id)topCGColor, (__bridge id)midCGColor]; }}
复制代码

2) 页面/卡片/图片打底色

这里是比较容易遗漏的,Loading 态,错误态,打底图都需要适配,否则页面容易出现“白块”影响整体暗黑效果。



Android 示例代码


//从颜色管理器中取出背景色 YKN_PRIMARY_BACKGROUND 为 Design Token定义的色值int bgColor=ColorConfigureManager.getInstance().getColorMap().get(YKN_PRIMARY_BACKGROUND)setFragmentBackGroundColor(bgColor);
复制代码


加载骨架图通过 Android 系统的资源寻址自动获得。


我们只需建立暗黑模式的资源目录(night),并把骨架图的 drawble 放进去即可。


iOS 示例代码


// Feed流Loading图通过动态资源方式获取itemView.image = [UIImage ykn_home_feed_loading_default];
/// 首页Feed流默认Loading图+ (UIImage *)ykn_home_feed_loading_default { return [UIImage ykn_imageWithThemeProvider:^UIImage * _Nonnull(__kindof YKNThemeManager * _Nonnull manager, NSString * _Nullable identifier, NSObject<YKNThemeProtocol> * _Nullable theme) { // 暗黑模式下的图 if ([identifier isEqualToString:YKNThemeIdentifierDark]) { return [UIImage imageNamed:@"home_feed_loading_default_d"] ; } // 浅色模式下的图 return [UIImage imageNamed:@"home_feed_loading_default"]; }];}
复制代码

3) 暗黑与氛围/换肤的兼容问题

优酷分发场景支持换肤、氛围和暗黑模式,优先级为氛围>换肤>暗黑。所有页面、组件都在此规则上进行适配。


a) 页面同时存在氛围+暗黑


电影频道为了培养频道用户的心智,定义了头部和轮播的氛围色。



b) 页面整体都是氛围


高清频道突出高清适配的质感,将整个高清频道页面都定义了氛围色。


2、组件级别

分发场景有几十种组件,大部分组件接入非常便捷,只需将引用的资源字段改为 DesignToken 即可;

1) 常规组件

这里 Android 和 iOS 实现有些差异,需要分别说明。


a) Android



Android 为了提高性能,有些文本绘制使用了自定义 View 来单独绘制文本,目的是减少 View 数量和减少 View 的 measure 时间,上图的 PhoneCommonTitlesWidget 就是一个封装了标题绘制的自定义 View。


下面的代码主要是说明了如何使用 DesignToken,使用 DesignToken 色值有两种方式。


第一种,通过 Layout 布局文件使用包含 DesignToken 的 Style,这种方式方式一般用于系统控件,或继承自系统控件的简单封装比如 YKTextView:


 <com.youku.resource.widget.YKTextView        android:id="@+id/title_context_1"        style="@style/text_view_1a"   //style        android:layout_width="wrap_content"        android:layout_height="match_parent"        android:gravity="start|center_vertical"        android:layout_marginLeft="@dimen/dim_6"        app:layout_goneMarginLeft="0dp"        app:layout_constraintTop_toTopOf="parent"        app:layout_constraintBottom_toBottomOf="parent"        app:layout_constraintStart_toEndOf="@id/title_left_icon"        />
<style name="text_view_1a"> <item name="android:textSize">@dimen/font_size_big1</item> <item name="android:textStyle">bold</item> <item name="android:singleLine">true</item> <item name="android:includeFontPadding">false</item> <item name="android:ellipsize">end</item> <item name="android:textColor">@color/ykn_primary_info</item> //DesignToken颜色 </style>
复制代码


第二种,通过代码使用 DesignToken 色值,这种一般是自定义 View 通过 draw 的方式来渲染 UI,比如上图中的 PhoneCommonTitlesWidget。


 Resources res = context.getResources(); //主标题字体size int sDefaultTitleTextSize = res.getDimensionPixelSize(R.dimen.font_size_middle1); //副标题字体size int sDefaultSubtitleTextSize = res.getDimensionPixelSize(R.dimen.font_size_middle4); //主标题DesignToken颜色 int sDefaultTitleTextColor = res.getColor(R.color.ykn_primary_info); //副标题DesignToken颜色 int sDefaultSubtitleTextColor = res.getColor(R.color.ykn_tertiary_info);
复制代码


b) iOS



有些组件业务逻辑复杂、视图的层级很深,找到相应的代码非常耗时,我们可以使用 Xcode 的 Debug 工具、也可以使用优酷开发的一套 UI 检查工具(啄木鸟),来快速适配暗黑模式。


// 标题:一级信息色Token_titleLabel.textColor = [UIColor ykn_primaryInfo];
// 子标题:二级信息色Token_subtitleLabel.textColor = [UIColor ykn_secondaryInfo];
// 边框:升起的一级组块背景Token_borderView.backgroundColor = [UIColor ykn_elevatedPrimaryBackground];
复制代码

2)特殊组件

优酷有些组件展示的主体是服务端下发的图片,但是服务端暂时不支持下发视频暗黑模式的图片。针对这种组件就需要有个降级策略,尽量保证暗黑模式的整体显示效果,这种属于特例情况要根据自己的业务特性来定义降级模式。



下面是一个具体的样例。

四、遇到的问题

1、Android

由于资源(color,drawable)是通用的,对于那些没有适配暗黑的页面要进行特殊处理。具体方式是: 在暗黑模式下进入没有适配暗黑的页面, 需要关闭暗黑模式来保证页面可以寻址到亮色的资源,在离开的时候再恢复暗黑模式。


在进入页面的时候关闭暗黑模式,Activity OnResume 中调用下面代码,关闭暗黑模式


//判断当前是否处在暗黑模式if (UIMode.getInstance().isDarkMode()) {    //关闭暗黑模式    appCompatActivity.getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO);
//更新颜色配置 ColorConfigureManager.getInstance().onConfigureChanged();}
复制代码


在离开或页面不可见时候恢复暗黑模式,Activity OnPause 中调用下面代码,恢复暗黑模式


//判断当前是否处在暗黑模式 if (UIMode.getInstance().isDarkMode()) {    //恢复暗黑模式    appCompatActivity.getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES);} else {    //关闭暗黑模式    appCompatActivity.getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO);}
//更新颜色配置ColorConfigureManager.getInstance().onConfigureChanged();
复制代码

2、iOS

  1. 渐变色处理方式不友好


iOS 上渐变色无法自动切换暗黑样式,只能通过监听暗黑模式变化通知,手动设置暗黑渐变样式。


  1. 对比系统原生暗黑


五、适配效果

六、总结

暗黑模式对于视频类应用可以明显提升用户体验,在观感上更适合沉浸式的深度浏览,对于夜晚使用能有效避免亮色模式“刺眼”, 对眼睛更加舒适。因为 LED 屏幕在显示黑色像素的时候并不发光,因而可以提升续航时间,看剧更持久。


用户主路径涉及到的页面,弹窗,甚至图片默认打底图,Loading 图,页面加载出来前的骨架图尽量都适配暗黑模式。由于人眼对由暗到亮比由亮到暗更敏感(例如: 黑夜中突然的车灯会晃得睁不眼睛),主业务场景的暗黑模式尽量避免亮色模式的 UI 元素带来视觉反差,破坏用户沉浸式浏览观看体验。


对于 Android 而言,暗黑模式在系统级的支持是从 Android 10 开始,目前 Android 10 的手机还没有大规模的系统升级。在开发中我们可以通过代码强制打开暗黑模式,方便进行开发。产品上也可以考虑在客户端的设置项中增加“强制暗黑模式”的开关,使得低于 Android 10 版本的手机也可以使用暗黑模式。


作者简介


叔平,阿里文娱无线高级开发工程师。


相关阅读


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


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


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


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


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


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


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


2020-02-27 15:001395

评论

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

产品经理训练营 Week11 学习心得

Mai

Redis 如何应对并发访问

escray

redis 学习 极客时间 3月日更 Redis 核心技术与实战

BI大数据分析系统开发,助力企业数字化转型

13828808769

区块链 区块链+ #区块链#

AI 事件驱动场景 Serverless 实践

Serverless Devs

Kubernetes 云原生 #Serverless

爱奇艺大数据生态的实时化建设

Apache Flink

flink 实时计算

用户路径地图+漏斗模型

mas

ECMAScript 2018(ES9)新特性简介

程序那些事

JavaScript ecmascript 程序那些事 es9

区块链推动知识产权数字化,区块链在知识产权中的价值体现

13828808769

区块链+ #区块链#

API 工具链研发的理论基础 - 流派

李宇飞

工具链 API

用户路径地图与漏洞模型

思亭

用户路径地图 漏洞模型

第8周用户路径数据分析作业

skylar

Python OpenCV 之像素的加减法,取经之旅第 15 天

梦想橡皮擦

3月日更

用户路径地图+漏斗模型总结

mas

带你全面认识CMMI V2.0(四)——管理 赋能

渠成CMMI

项目管理 CMMI

APP 防重放实现

草原狼

安全 API 防重放

如何处理分析Flink作业反压的问题?

华为云开发者联盟

实时计算 DWS Flink作业 反压 Sink

云原生AI成过去式,AI原生的云才是通向未来的“藏宝图”

脑极体

Kubernetes v1.21 新特性预览

倪朋飞

Kubernetes 云原生

kylin基本概念和原理

潮湿了我押韵的心情

「产品经理训练营0期」第八周作业

🌟

产品 产品经理训练营

产品经理训练营第八章作业

新盛

NA(Nirvana) Chain主打应用而生NA公链NAC公链

区块链第一资讯

面向复杂度架构设计的思考

Simon

架构实战营

搭建 Mac 系统下的 C++开发环境

Jack—Li

架构师:始于理性思考,成于科学实践——郭东白老师分享总结

青春不可负,生活不可欺

成长 架构设计 架构师

SpringCloud技术专题-Hystrix以及FeginClient异常

洛神灬殇

SpringCloud Fegin

C++中结构体的定义

Jack—Li

「架构师训练营 4 期」 第十二周 - 001&2

凯迪

架构师训练营 4 期

Rust从0到1-基础概念-控制流

rust 控制流

centos7docker安装

happlyfox

Docker 学习 3月日更

订单和产品的多对多表关系在crudapi系统零代码实现

crudapi

API crud crudapi 一对多 多对一

优酷暗黑模式(八):分发场景落地(Android & iOS)_移动_阿里巴巴文娱技术_InfoQ精选文章