Android - 深色主题

news2024/11/15 22:29:00

一、简介

我们一直以来使用的操作系统都是以浅色主题为主的,这种主题模式在白天或者是光线充足的 情况下使用起来没有任何问题,可是在夜晚灯光关闭的情况下使用就会显得非常刺眼。 于是,许多应用程序为了能够让用户在光线昏暗的环境下更加舒适地使用,会在应用内部提供 一个一键切换夜间模式的按钮。当用户开启了夜间模式,就会将应用程序的整体色调都调整成 更加适合于夜间浏览的颜色。 不过,这种由应用程序自发实现夜间模式的方式很难做到全局统一,即有些应用可能支持夜间 模式,有些应用却不支持。而且重复操作的问题也很让人头疼,比如说我在一个应用中开启了 夜间模式,在另外一个应用中还需要再开启一次,关闭夜间模式也需要进行同样重复的操作。 因此,很多开发者一直呼吁,希望Android能够在系统层面支持夜间模式功能。

终于在Android 10.0系统中,Google引入了深色主题这一特性,从而让夜间模式正式成为了官方支持的功能。 或许你会有些疑惑,这种看上去并没有太多技术难度的功能,为什么Android直到10.0系统中 才进行支持呢?这是因为仅仅操作系统自身支持深色主题是没有用的,还得让所有的应用程序 都能够支持才行,而这从来都不是一件容易的事情。 为此,我希望你以后开发的应用程序都能够按照Android系统的要求对深色主题进行很好地支 持,不然当用户开启了深色主题之后,只有你的应用还使用的是浅色主题的话,就会显得格格 不入。

除了让眼部在夜间使用时更加舒适之外,深色主题还可以减少电量消耗,从而延长手机续航, 是一项非常有用的功能。

二、Force Dark

它是一种能让应用程序快速适配深色主题,并且 几乎不用编写额外代码的方式。Force Dark的工作原理是系统会分析浅色主题应用下的每一层 View,并且在这些View绘制到屏幕之前,自动将它们的颜色转换成更加适合深色主题的颜色。 注意,只有原本使用浅色主题的应用才能使用这种方式,如果你的应用原本使用的就是深色主题,Force Dark将不会起作用。

这里我们尝试对MaterialTest项目使用Force Dark转换来进行举例。启用Force Dark功能需要 借助android:forceDarkAllowed属性,不过这个属性是从API 29,也就是Android 10.0 系统开始才有的,之前的系统无法指定这个属性。因此,我们得进行一些系统差异型编程才 行。

1、右击res目录→New→Directory,创建一个values-v29目录,然后右击values-v29目录 →New→Values resource file,创建一个styles.xml文件。接着对这个文件进行编写,代码如 下所示:

<resources>
 <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
 <item name="colorPrimary">@color/colorPrimary</item>
 <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
 <item name="colorAccent">@color/colorAccent</item>
 <item name="android:forceDarkAllowed">true</item>
 </style>
</resources>

除了android:forceDarkAllowed属性之外,其他的内容都是从之前的styles.xml文件中复 制过来的。这里给AppTheme主题增加了android:forceDarkAllowed属性并设置为 true,说明现在我们是允许系统使用Force Dark将应用强制转换成深色主题的。另外, values-v29目录是只有Android 10.0及以上的系统才会去读取的,因此这是一种系统差异型编 程的实现方式。

Force Dark就是这样一种简单粗暴的转换方式,并且它的转换效果通常是不尽如人意的。因 此,这里我并不推荐你使用这种自动化的方式来实现深色主题,而是应该使用更加传统的实现 方式——

三、手动实现

要想实现最佳的深色主题效果,不要指望有什么神奇魔法能够一键完成,而是应该针对 每一个界面都进行浅色和深色两种主题的界面设计。这听上去好像有点复杂,不过我们仍然有 一些好用的技巧能让这个过程变得简单。

AppCompat库内置的主题恰好主要分为浅色主题和深色主题两 类,比如MaterialTest项目中目前使用的Theme.AppCompat.Light.NoActionBar就是浅色 主题,而Theme.AppCompat.NoActionBar就是深色主题。选用不同的主题,在控件的默认 颜色等方面会有完全不同的效果。

而现在,我们多了一个DayNight主题的选项。使用了这个主题后,当用户在系统设置中开启深 色主题时,应用程序会自动使用深色主题,反之则会使用浅色主题。

1、首先删除values-v29目录及其目录下的内容,然后修改 values/styles.xml中的代码

<resources>
 <!-- Base application theme. -->
 <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
 <!-- Customize your theme here. -->
 <item name="colorPrimary">@color/colorPrimary</item>
 <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
 <item name="colorAccent">@color/colorAccent</item>
 </style>
 ...
</resources>

可以看到,这里我们将AppTheme的parent主题指定成了 Theme.AppCompat.DayNight.NoActionBar,这是一种DayNight主题。因此,在普通情况 下MaterialTest项目仍然会使用浅色主题,和之前并没有什么区别,但是一旦用户在系统设置 中开启了深色主题,MaterialTest项目就会自动使用相应的深色主题。

2、DayNight主题的效果

虽然现在界面中的主要内容都已经自动切换成了深色主题,但是你会发现标题栏和悬浮 按钮仍然保持着和浅色主题时一样的颜色。这是因为标题栏以及悬浮按钮使用的是我们定义在 colors.xml中的几种颜色值,代码如下所示:

<resources>
 <color name="colorPrimary">#008577</color>
 <color name="colorPrimaryDark">#00574B</color>
 <color name="colorAccent">#D81B60</color>
</resources>

这种指定颜色值引用的方式相当于对控件的颜色进行了硬编码,DayNight主题是不能对这些颜 色进行动态转换的。

好在解决方案也并不复杂,我们只需要进行一些主题差异型编程就可以了。右击res目录 →New→Directory,创建一个values-night目录,然后右击values-night目录 →New→Values resource file,创建一个colors.xml文件。接着在这个文件中指定深色主题下 的颜色值

虽说使用主题差异型的编程方式几乎可以帮你解决所有的适配问题,但是在DayNight主题下, 我们最好还是尽量减少通过硬编码的方式来指定控件的颜色,而是应该更多地使用能够根据当 前主题自动切换颜色的主题属性。比如说黑色的文字通常应该衬托在白色的背景下,反之白色 的文字通常应该衬托在黑色的背景下,那么此时我们就可以使用主题属性来指定背景以及文字 的颜色,示例写法如下:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="?android:attr/colorBackground">
 <TextView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_gravity="center"
 android:text="Hello world"
 android:textSize="40sp"
 android:textColor="?android:attr/textColorPrimary" />
</FrameLayout>

这些主题属性会自动根据系统当前的主题模式选择最合适的颜色值呈现给用户

另外,或许你还会有一些特殊的需求,比如要在浅色主题和深色主题下分别执行不同的代码逻 辑。对此Android也是支持的,你可以使用如下代码在任何时候判断当前系统是否是深色主题:

fun isDarkTheme(context: Context): Boolean {
 val flag = context.resources.configuration.uiMode and
 Configuration.UI_MODE_NIGHT_MASK
 return flag == Configuration.UI_MODE_NIGHT_YES
}

调用isDarkTheme ()方法,判断当前系统是浅色主题还是深色主题,然后根据返回值执行不 同的代码逻辑即可。

另外,由于Kotlin取消了按位运算符的写法,改成了使用英文关键字,因此上述代码中的and关 键字其实就对应了Java中的&运算符,而Kotlin中的or关键字对应了Java中的|运算符,xor关 键字对应了Java中的^运算符,非常好理解。

最后贴上自己的

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/488007.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mysql使用innodb引擎,请简述mysql索引的最左前缀如何优化orderby语句。

关键点 如果排序字段不在索引列上&#xff0c;filesort有两种算法&#xff1a; mysql就要启动双路排序和单路排序无过滤不索引order by非最左 filesort顺序错 filesort方向反 filesort 答案 首先要对sql进行分析检查必要的查询字段&#xff0c;过滤字段&#xff0c;排序字段…

JeecgBoot免费低代码平台—多租户SAAS解决方案

JeecgBoot免费低代码平台&#xff0c;提供一键切换多租户模式机制&#xff01;快速实现全系统的saas租户方案&#xff0c;通过租户ID进行数据隔离。 租户设计思路 1、开启全系统租户隔离 开启方法 将 org.jeecg.config.mybatis.MybatisPlusSaasConfig#OPEN_SYSTEM_TENANT_CO…

Selenium:浏览器及鼠标、键盘事件

目录 一、控制浏览器 二、鼠标事件 三、键盘事件 一、控制浏览器 webdriver主要提供操作页面上各种元素的方法&#xff0c;但它也提供操作浏览器的一些方法&#xff0c;例如控制浏览器大小、前进和后退等。 1、控制浏览器窗口大小 1 # 控制浏览器大小 2 from selenium imp…

2023哪款蓝牙耳机性价比高?200左右高性价比蓝牙耳机推荐

现如今的蓝牙耳机越来越多&#xff0c;人们在选择时不免纠结&#xff0c;不知道选什么蓝牙耳机比较好&#xff1f;针对这个问题&#xff0c;我来给大家推荐几款性价比高的蓝牙耳机&#xff0c;一起来看看吧。 一、南卡小音舱Lite2蓝牙耳机 参考价&#xff1a;299 蓝牙版本&am…

常见提高SQL执行效率示例

1、减少与数据库的交互&#xff1a; 当传参是一个list集合时&#xff0c;通过遍历查询数据库会造成数据库压力过大&#xff0c;这样查询效率就比较低&#xff0c;应该减少与数据库的交互来提高查询效率&#xff1a;(这里的objId为“ljydl”,"ljtpfl") QueryWrapper&…

JavaScript全解析——本地存储的概念、用法详解

本地存储概念&#xff1a; 就是浏览器给我们提供的可以让我们在浏览器上保存一些数据 常用的本地存储 localStorage sessionStorage localStorage 特点: 1.长期存储,除非手动删除否则会一直保存在浏览器中&#xff0c;清除缓存或者卸载浏览器也就没有了 2.可以跨页面通讯,…

如何设计出结构清晰布局漂亮的SWC结构图

我们都知道AUTOSAR的设计理念是自顶向下的设计,并且现在使用的很多AUTOSAR工具链对于SWC的设计都支持模型设计,以Vector Developer工具为例,假设我们不调整Composition,其结构图显示将会比较乱,比如如下这个样子,结构图中ports关系不清晰,位置重叠,布局不够清晰,有些朋…

二维码在设备管理中的应用

对设备进行巡检是工厂日常管理中必不可少的工作之一&#xff0c;从前很多工厂使用纸质记录打钩的方式进行设备巡检&#xff0c;但纸质巡检单不易保存也不方便进行查阅或汇总&#xff0c;除此之外光靠打钩很难保证巡检的真实性&#xff0c;不能起到防假检的功能。 为了让设备巡…

vue3+Typescript实现路由标签页和面包屑

文章目录 在vue中实现路由标签页和面包屑需求分析最终效果实现步骤第一步&#xff1a;创建路由标签组件和面包屑第二步&#xff1a;创建路由标签数组第三步&#xff1a;监听路由变化并自动添加新标签第四步&#xff1a;处理关闭标签事件第五步&#xff1a;当前路由标题同步面包…

Oracle RAC 19c集群搭建指南:实现高可用、高性能的数据库集群(超详细)

Oracle RAC 19c集群搭建指南&#xff1a;实现高可用、高性能的数据库集群&#xff08;超详细&#xff09; 1.新建节点 因为rac集群使用的是共享盘&#xff08;esxi设置共享盘步骤如下&#xff09;&#xff1a; 首先添加一个iSCSI控制器SCSI总线共享选择虚拟添加硬盘&#xf…

java:fastjson,jackson自定义反序列化器设计暨jackson反序列化时出现StackOverflowError异常的原因分析

问题描述 如下是一个Java Bean类&#xff0c;这是我的sql2java工具根据数据库表自动生成的对应表记录的Java类。 与之对应的数据库表定义如下&#xff1a; CREATE TABLE IF NOT EXISTS dc_device_channel (device_id int NOT NULL COMMENT XNAME:设备IDX,sid …

一种具备过载检测和打嗝式保护功能的MBUS主机电路

关于MBUS电路原理和简化电路见本篇文章&#xff0c; MBUS主机端简化版电路设计_Tech-Wang的博客-CSDN博客https://blog.csdn.net/jsf120/article/details/123378064?spm1001.2014.3001.5502 上篇中的电路已经验证通过并在产品中实际应用&#xff0c;本篇在此基础上增加了打嗝…

itop-3568开发板驱动学习笔记(25)设备树(四)GPIO 实例分析

《【北京迅为】itop-3568开发板驱动开发指南.pdf》 学习笔记 文章目录 GPIO 控制器必要属性其他属性 指定 GPIO 引脚 和时钟类似&#xff0c;GPIO 在设备树中也存在两层定义&#xff0c;首先是 GPIO 控制器&#xff0c;这部分由芯片原厂工程师编写&#xff0c;相当于 GPIO 底层…

恺撒密码太简单?这样一改,秒变地狱级难度(37)

小朋友们好&#xff0c;大朋友们好&#xff01; 我是猫妹&#xff0c;一名爱上Python编程的小学生。 欢迎和猫妹一起&#xff0c;趣味学Python。 今日主题 看过上一篇文章的朋友&#xff0c;可能觉得这样加密&#xff0c;未免太简单了吧&#xff1f; 一共26个字母&#xf…

【java】一文让你了解透彻Java中的IO模型

文章目录 前言一、什么是IO二、常见的IO模型BIO&#xff08;Blocking IO&#xff09;如何优化NIO的面世 三、NIO&#xff08;Non-blocking/New IO&#xff09;同步非阻塞IO模型IO多路复用模型Java中的NIO 四、AIO&#xff08;Asynchronous IO&#xff09;总结 前言 本文只是说…

不要一昧的给孩子做骨密度检查,这些情况才要做

国内&#xff0c;骨密度检测应用非常广泛。也成了很多医院儿科常规的体检项目之一。而在儿科领域&#xff0c;对骨密度检查的必要性、临床参考意义一直颇有争议。 有专家说&#xff0c;“孩子需要及时检测骨密度&#xff0c;但是要用科学有效的检测方式……只有双能X线的检测方…

BetaFlight统一硬件配置文件研读

BetaFlight统一硬件配置文件研读 1. 源由2. 分析2.1 硬件SOC2.2 统一配置文件2.3 cli命令2.4 板级配置主要命令2.4.1 board_name2.4.2 manufacturer_id2.4.3 resource2.4.4 timer2.4.5 dma2.4.6 serial2.4.7 set2.4.8 feature 3. 实例研读3.1 C遗留配置3.2 BoardName - AOCODAR…

asp.net+C#基于web的失物招领系统ccA1A9程序

根据分析&#xff0c;该系统应该有二个角色&#xff1a;管理员、注册用户。系统需要赋予他们对应的功能和权限&#xff0c;具体如下&#xff1a; 管理员具有&#xff1a;管理管理注册用户、管理新闻模块、管理留言的功能和权限。 具有&#xff1a;浏览新闻、管理失物信息、参与…

【Linux内幕】DMA原理

1.前言 I/O设备与主存信息传送的控制方式分为程序轮询、中断、DMA、RDMA等。 2.DMA介绍 DMA&#xff0c;全称Direct Memory Access&#xff0c;即直接存储器访问。 DMA传输将数据从一个地址空间复制到另一个地址空间&#xff0c;提供在外设和存储器之间或者存储器和存储器之…

GAT1400-视图库标准

一、简述&#xff1a; GA/T 1400是于2017年首次发布关于图片、视频片段、文件等属性对象的传输协议。 GA/T 1400《公安视频图像信息应用系统》分成4个部分&#xff1a; 第一部分–通用技术要求&#xff1b; 第二部分–应用平台技术要求&#xff1b; 第三部分–数据库技术要…