在Android 10 开始安卓开始支持暗黑模式,个人感觉是仿照ios 来做的,不过android 的碎片化比较严重,各个厂商定制严重,没有办法去强制推广,ios 在系统升级13 并且必须适配暗黑模式,看看吧,人家是强制.但是我们也不能落后啊.

1.如何开启android  10 中的暗黑模式

不同厂商对于叫法不太相同,但是大概位置都会放到  设置---->>  显示和亮度  ----->>  暗黑或者深色模式

我的华为mate20是这样的,具体以个人手机为准,安卓原生在 ---->设置--->显示----> dark theme,大家一看就懂。

2.啥是暗黑模式

所谓的暗黑就是将我们的应用的主题色调到趋向于黑或者灰色,总体给人的感觉就是比较柔和不像白色高亮那么刺眼,还有更重要的一点,省电,降低功耗,现在手机的屏幕是越来越大,厚度也在降低,相对于先前的一些外观尺寸相同的手机,明显续航能力弱了很多,电池也小了,所以为了续航为了更好的体验总的做点啥吧,并且现在主流设备使用的多是 LED 屏和 OLED 屏,他俩的发光原理不同.

LED :屏幕的显示模式为屏幕背光模组照亮整个屏幕,即便是显示纯黑色时背光模组也会工作

OLED :屏幕的发光特性,显示纯黑色时像素是完全不发光,OLED 屏幕如果长时间显示深色像素时便会比浅色像素更加省电。

所以我们所说的的暗黑模式主要有两个方面的优点:

1.暗黑模式可以帮助对光线较为敏感,或视力有问题的用户看清楚手机,也可让所有用户在低光环境下更舒适地看屏幕

2.在OLED 屏上大幅度的降低电量的消耗,延长设备使用时间

适配原理:

适配原理其实类似于我们适配横竖屏一样,我们创建一个暗黑模式文夹一般都带night 关键字,然后将相同名字的资源文件放到不同的文件夹下,系统会主动根据当前设备的模式去相应的文件夹找资源。

适配主要的几个点

1.文字颜色,不同模式下相同的组件的颜色会有变化,比如暗黑模式你的文字必须是以白色为主的,白色或者亮色模式下是以黑色为主,否则就会看不清或者看不到,这里是最大的坑,有些颜色是根据业务在代码中动态设置的,很有可能你的背景是白色的,然后你的字体颜色也是白的,这个就比较坑了,需要注意,因为我们的app本来就是默认暗色的,现在要把暗色主题等的默认改成白色的主题,然后适配暗黑模式,之前文字图片大多是白色的或者透明的,在把主题改为白色后文字就看不到了,所以要关注每个空间xml中和代码中两个地方的文字颜色修改,否则就看不到,因为白色的底和白色的字,这个鬼才看得见,所以最好的办法就是同一个页面在两种模式切换下,进行对比,当然这样成本比较高,页面太多,当然如果你的团队操作比较规范比如颜色是有过约束的,没有用到硬编码,那这个就比较好改,只要从源头改掉基本就完事了。

2.图片适配和文字基本是一个道理,除非使用了其他比较鲜艳的颜色图片,无论是暗黑或者亮白都可以看的很清楚或者视觉效果都不错

3.状态栏和导航栏修改,因为我们大多使用的是自定义的暗黑模式适配,所以状态栏是不会随着系统设置去改变的,所以在白色主题下我们要将状态栏调为黑色,暗色时调节为白色,当然了一般导航栏是和主题颜色一样的,一般不用改,只要配置好主题

4.主题修改,因为app 页面太多了,所以只改了一级和主要二级页面,所以需要将适配的去修改主题

5.切换模式生命周期重新执行了,带来的数据丢失,比较明显的是tab 页切换时,当前内容页和当前的tab 页标签对不上,这里要做一个数据保存

下面我们进入正题,从头开始撸。

1.颜色的定义 color

在项目的res 目录下新建values-night 文件夹,然后在里边新建colors文件,定义如下颜色

<?xml version="1.0" encoding="utf-8"?>
<resources><!--    这个用于暗黑模式主色调--><color name="main_bg_1">@android:color/black</color><!--    这个用于普通亮色模式辅助色调--><color name="main_bg_2">#1B1818</color><!--    主要文字颜色 用于主标题等--><color name="main_text_1">@android:color/white</color><!--    次要文字颜色 用于副标题--><color name="main_text_2">#999999</color></resources>

然后我们在values下的colors 下 创建相同的颜色标签名字,把 后边的颜色值改下

<!--    这个用于普通亮色模式主色调--><color name="main_bg_1">@android:color/white</color><!--    这个用于辅助背景色调--><color name="main_bg_2">#999999</color><!--    主要文字颜色 用于主标题等--><color name="main_text_1">@android:color/black</color><!--    次要文字颜色 用于副标题--><color name="main_text_2">#1B1818</color>

这个是普通模式下的。

2.主题定义

然后们定义一个主题,并且使用该颜色值

    <style name="DarkTheme" parent="Theme.AppCompat.DayNight.NoActionBar"><item name="colorPrimary">@color/main_bg_1</item><item name="colorPrimaryDark">@color/main_bg_1</item><item name="colorAccent">@color/main_bg_1</item></style>

然后在你需要适配的activity mainfist 中使用该主题,注意主题必须是DayNight 类型主题的子类

android:theme="@style/DarkTheme"

3.代码及xml 使用

在xml 中使用

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:background="@color/main_bg_2"android:orientation="vertical"android:layout_margin="20dp"android:gravity="center"android:padding="20dp"app:layout_constraintTop_toTopOf="parent"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="我是一个标题"android:textSize="20sp"android:textColor="@color/main_text_1"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="40dp"android:text="我是一个辅助标题"android:textSize="20sp"android:textColor="@color/main_text_1"/></LinearLayout></androidx.constraintlayout.widget.ConstraintLayout>

首先这个页面我没有设置背景色,他的背景色是跟随主题的,如果你硬要给他一个,那么在系统切换模式的时候就会失效,其次这里使用的颜色是我们之前定义过的色值,他会根据不同的设置模式去自动选择使用那种颜色,如,night 文件夹中的就是暗黑模式下的色值。

关于字体及背景色简单总结:

这是文字及背景色的适配,基本就这些,但是正式运用到项目中就不会这么简单,因为你可能会有很多种颜色,每种颜色大多分为白色背景下的和黑色背景下的,比较难管理,通过我在整个项目的实践,我的建议是,一种模式下主要字体颜色最多定义三种,就比如说我上边使用到的,我只用了两种,主标题和副标题颜色以及主背景和副背景色,这样比较好管理,至于其他比较鲜艳的颜色黑白都能用的,就可以定义在普模式的colors 文件夹下,两种模式公用。

4.关于图片的适配

图片的适配和颜色是一个道理 比如说 我们的在drawable 文件下有一张图需要适配两种模式,那就新建一个文件夹darwable-night

,将需要在暗黑模式中需要使用的图片放到darwable-night下,需要注意的是,文件名一定要相同,还有就是在night相关文件定义了资源,那么在普通模式文件夹下一定要有相同名的资源,不然会报错。

反之就不用了。

5.状态栏的修改

如果你按照上面我说的去做了,那么你会发现一个很操蛋的问题,在暗黑模式下没有啥问题,但是在白色模式下状态栏看不到了,

这个我上面说过,我们要手动的设置状态栏颜色,看不见的原因是系统默认是白色的状态栏,遇到白色背景肯定就看不到了,所以我们要坚获取到当前是否是暗黑模式然后修改状态栏颜色。

 private void setAndroidNativeLightStatusBar(Activity activity, boolean dark) {Log.d(TAG, "setAndroidNativeLightStatusBar: " + dark);View decor = activity.getWindow().getDecorView();if (dark) { //暗黑 设置状态栏为白色decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);} else {//设置状态栏为黑色decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);}}

这是谷歌给出的方法.

那我咋知道当前是不是暗黑模式呢? 这里有两种方式

方式一:

在mainfist 中activity 添加

<activity android:name=".MainActivity"android:configChanges="uiMode">

android:configChanges="uiMode" 这样在用户切换暗黑模式后进入到app 时

 @Overridepublic void onConfigurationChanged(@NonNull Configuration newConfig) {
when (newConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK) {Configuration.UI_MODE_NIGHT_YES -> {// 暗黑模式已开启}Configuration.UI_MODE_NIGHT_NO -> {// 暗黑模式已关闭}}

方法就会被调用,但是这时系统设置暗黑主题后,在app是无效的,他的oncreate 没有重新执行,也就是app 当前页还没刷新过来,新开的页面就是好的,所以需要oncreate 重新执行才可以,要手动控制,还有就是我们可以根据这个去切换两个不同的主题,并且还是在setContentView 前,通过setTheme()设置主题,这样我们需要定义两套主题,我个人觉得不可取,所以我也没有使用这种方式,这个也是我之前遇到的一个坑,当设置了  android:configChanges="uiMode"  切换系统主题,app 主题一直没有变换.

方式二:

直接在当前activity 判断当前activity 是否是暗黑模式,如果是就设置状态栏为白色,不是就设置为黑色

//检查当前系统是否已开启暗黑模式public static boolean getDarkModeStatus(Context context) {int mode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;return mode == Configuration.UI_MODE_NIGHT_YES;}

然后调用 setAndroidNativeLightStatusBar(this,isDark)方法设置状态栏,这样基本就完美,当然这个只要我们把它放在父类中就好了,比较简单。

看下MainActivity

public class MainActivity extends Activity {private static final String TAG = "MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);if (savedInstanceState!=null) {String tag = (String) savedInstanceState.get("tag");}setContentView(R.layout.activity_main);setAndroidNativeLightStatusBar(this, getDarkModeStatus(this));Log.d(TAG, "onCreate: ");}private void setAndroidNativeLightStatusBar(Activity activity, boolean dark) {Log.d(TAG, "setAndroidNativeLightStatusBar: " + dark);View decor = activity.getWindow().getDecorView();if (dark) { //暗黑 设置状态栏为白色decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);} else {//设置状态栏为黑色decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);}}@Overridepublic void onConfigurationChanged(@NonNull Configuration newConfig) {super.onConfigurationChanged(newConfig);Log.d(TAG, "onConfigurationChanged: ");}public static boolean getDarkModeStatus(Context context) {int mode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;return mode == Configuration.UI_MODE_NIGHT_YES;}@Overrideprotected void onSaveInstanceState(@NonNull Bundle outState) {super.onSaveInstanceState(outState);outState.putString("tag","");}
}

6.最后一坑,tab标签页选项和内容fragmeng 不匹配

上面我们说了,在系统切换主题时当前activity 的生命周期会重新执行,目的就是刷行刚刚设置的主题,但是oncreate 重新执行带来了数据丢失,出现tab 标签和tab 标签页的fragment 内容不符.

这时就要保存数据了,通过重写

  @Overrideprotected void onSaveInstanceState(@NonNull Bundle outState) {super.onSaveInstanceState(outState);outState.putString("tag","");}

将数据保存在outState Bundle 中。在oncreate 中取出即可

 if (savedInstanceState!=null) {String tag = (String) savedInstanceState.get("tag");}

到此为止本次适配过程中遇到的所有问题都解决了

android 暗黑模式项目适配过程相关推荐

  1. Android 暗黑模式适配

    Android 暗黑模式适配 不爱废话直接上菜. 第一种适配方式: 1.1 直接修改APP主题,values/styles.xml 如下: <style name="AppTheme& ...

  2. Android App Dark Theme(暗黑模式)适配指南,android实战mysql

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v2qd7l5a-1636430548017)(https://user-gold-cdn.xitu.io/2020/3/ ...

  3. Android App Dark Theme(暗黑模式)适配指南

    在 2019 年的 Google I/O 和 Apple WWDC 上,新露面的 Android 10 和 iOS 13 都宣布将支持 Dark Theme 也就是我们常说的暗黑模式,并提供相关 AP ...

  4. Android暗黑模式适配

    前言 最近这两年,用户关于支持暗黑模式的呼声越来越高.而友商也基本都上了暗黑模式,于是老板也要求我们年前得上,可是工作量太大了,200多个页面,一个人整,实在是没法年前发,就拖到了年后上. 成果 1. ...

  5. Android暗黑模式

    安卓适配暗黑模式 前言 第一次听到暗黑模式的时候,感觉好酷啊,听着就好看(也不知道我怎么听出来的).苹果在前几年就有暗黑模式的风声,好像是在IOS11.IOS12的时候就说要推出了,结果愣生生等到了I ...

  6. iOS 13.0 暗黑模式的适配

    一.暗黑模式的原理 将原本的资源文件,创建出两种不同的模式.根据不同的模式,自动获取该样式的资源. 每次切换系统模式的时候,系统会重新调用一些方法,重新赋值. 二.暗黑模式适配主要考虑的是: 1. 图 ...

  7. iOS 13适配——暗黑模式

    暗黑模式介绍 Implementing Dark Mode on iOS How To Adopt Dark Mode In Your iOS App Adopting iOS Dark Mode S ...

  8. Android 适配Dark Theme(暗黑模式),看完跪了

    Force Dark自动适配 Android 10 提供 Force Dark 功能.此功能可让开发者快速实现深色主题背景,只需要在 style.xml 中的应用主题中添加这一行代码android:f ...

  9. Android 适配Dark Theme(暗黑模式),Android高级工程师必备知识

    Android 10 提供 Force Dark 功能.此功能可让开发者快速实现深色主题背景,只需要在 style.xml 中的应用主题中添加这一行代码android:forceDarkAllowed ...

  10. 暗黑模式(黑暗模式,深色模式)适配

    暗黑模式(黑暗模式,深色模式)适配 全局关闭 打开Info.plist 项目配置文件,添加UIUserInterfaceStyle字段,key类型为String, 其value值设置为 Light模式 ...

最新文章

  1. bzoj1036: [ZJOI2008]树的统计Count 树链剖分
  2. RHEV平台中如何在 RED HAT ENTERPRISE LINUX 虚拟机上安装 GUEST 代理和驱动
  3. 特征工程(3):特征选择
  4. Redis 基本数据类型 :String、Hash、List、Set、ZSet
  5. 如何制作计算机启动盘,一款U盘启动盘制作小工具
  6. python 输入字符串_输入输出,字符串如影随形 | Python基础连载(五)
  7. c++面向对象高级编程 学习十六 vptr和vtbl
  8. python下载文件加上日期_Python实现给下载文件显示进度条和下载时间代码
  9. android js 代码混淆工具,好用的JS(Javascript)混淆加密工具-HDS JSObfuscator 2.14版
  10. C语言中连续两个printf,在C中两个连续的printf()调用的奇怪行为
  11. 【围棋棋盘绘制——html实现】
  12. dubbo服务暴露流程总结
  13. 小心身份证复印件的使用
  14. echarts地图下钻与回钻
  15. android商户扫码枪读取手机二维码
  16. c语言中调用函数fn,C语言常见的函数调用
  17. 山东省第五届ACM大学生程序设计竞赛 Weighted Median
  18. Alpha策略 股票-股指对冲
  19. 基于语音控制的智能家居实现
  20. MATLAB 声音文件处理

热门文章

  1. iOS:Autolayout自动布局实例
  2. Linux系统无法载入nvidia-smi驱动
  3. UBUNTU设置SSH通过密钥登陆
  4. Java知识总结,不止为了秋招(下)!!!
  5. 标记集合 java编译_深入理解Java虚拟机读书笔记-java编译期和运行期优化
  6. MFC中CDC画线总结
  7. arch Linux安装到U盘,如何把ArchLinux安装到U盘上
  8. c#遍历匹配串口(向每个串口发数据,根据返回数据确定是否为所需串口)
  9. 安卓rom制作教程_安卓手机TWRP_Recovery卡刷图文教程 适用于卡刷ROM,TWRP救砖
  10. 22-微信小程序商城 我的订单(微信小程序商城开发、小程序毕业设计、小程序源代码)(黄菊华-微信小程序开发教程)