关于Android10 暗黑模式的简述

前言

Android 10系统增加了暗黑模式,但是并没有像IOS那样强制适配。暗黑模式下可大幅减少耗电量。而且在晚上使用手机的情况下可以有效的保护视力,减少对眼睛的伤害。这个可以在手机的“设置->显示和亮度->深色模式”进行切换。(以华为手机为例)
暗黑模式一般由两种适配方法,下面我们就一起来了解Android 10系统的暗黑模式的两种适配方法。(注意:这里前提是要把项目的targetSdkVersion 设置为29 )

手动适配

手动适配相对来说比较简单,就是类似于之前的屏幕适配。比如适配颜色的话,就在res 下新建 values-night目录,创建对应的colors.xml文件。如果适配图片的话,就创建对应的 drawable-night目录。
下面我们就一起来尝试一下:

写一个布局,里面有图片和文字:

<?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">

    <ImageView
        android:id="@+id/iv_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:src="@drawable/icon_pause"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="文字颜色"
        android:textColor="@color/color_content"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/iv_image" />

    <TextView
        android:id="@+id/tv_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/bt_paly"
        android:layout_width="200dp"
        android:layout_height="50dp"
        android:layout_marginTop="20dp"
        android:text="播放"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/tv_text" />

    <Button
        android:id="@+id/bt_pause"
        android:layout_width="200dp"
        android:layout_height="50dp"
        android:layout_marginTop="20dp"
        android:text="暂停"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/bt_paly" />

</androidx.constraintlayout.widget.ConstraintLayout>

针对适配图片:在res文件夹下创建了两个文件夹,drawable-xhdpi用于放置白天模式下的图片,和drawable-night-xhdpi用于放置黑夜模式下的图片。

针对适配文字颜色:在values下有一个colors.xml文件用于书写白天模式下的颜色值,在res文件夹下创建一个values-night文件夹,里面同样创建一个colors.xml文件,用于书写黑夜模式下的颜色值。

关于Android10 暗黑模式的简述_第1张图片关于Android10 暗黑模式的简述_第2张图片
我们现在设置白天模式下图片加载:
关于Android10 暗黑模式的简述_第3张图片
颜色值设置:

<color name="color_content">#FF0000</color>

黑夜模式设置图片加载:
关于Android10 暗黑模式的简述_第4张图片
颜色值设置:

<color name="color_content">#FFFFFF</color>

运行之后,看一下效果:
关于Android10 暗黑模式的简述_第5张图片关于Android10 暗黑模式的简述_第6张图片好了,手动适配的方式就介绍到这里,手动适配其实说白了就是资源适配。

自动适配

Android10 提供了一种自动适配的方式,即Fork Dark。应用可以通过设置 android:forceDarkAllowed=“true”,来实现暗黑模式的自动适配。

注意:如果使用Dark Theme主题(例如Theme.Material),则系统不会应用 Force Dark。同样,如果应用的主题继承自 DayNight 主题(例如Theme.AppCompat.DayNight),则系统不会应用 Force Dark。
如果使用的是 DayNight 或 Dark Theme 主题,则设置forceDarkAllowed 不生效。

此外还可以通过setForceDarkAllowed(boolean) 在特定的View上控制 Force Dark。

例:在res文件夹下,新建一个values-29的文件夹,里面新建一个styles.xml的文件,里面写上在暗黑模式下要设置的Theme。
关于Android10 暗黑模式的简述_第7张图片关于Android10 暗黑模式的简述_第8张图片这时候,在系统设置里面,把系统切换为暗黑模式,那么当前App就会使用values-29文件夹下的styles.xml文件里面的AppTheme主题。关于Android10 暗黑模式的简述_第9张图片但是这里要注意的是,因为主题是:

parent="Theme.AppCompat.DayNight.DarkActionBar"

所以,这里的

<item name="android:forceDarkAllowed">false</item>

不管设置为true或者false,forceDarkAllowed都不会生效。

如果主题设置的是:

parent="Theme.AppCompat.Light.DarkActionBar"

那么当forceDarkAllowed为false的时候,显示白天模式,当forceDarkAllowed为true的时候,显示暗黑模式。此时,forceDarkAllowed的设置是生效的。

<item name="android:forceDarkAllowed">false</item>
<item name="android:forceDarkAllowed">true</item>

手动切换主题

此外,我们还可以通过 AppCompatDelegate.setDefaultNightMode(@NightMode int mode)方法手动切换主题:

public static class ThemeHelper {

        public static final String LIGHT_MODE = "light";
        public static final String DARK_MODE = "dark";
        public static final String DEFAULT_MODE = "default";

        public static void applyTheme(@NonNull String themePref) {
            switch (themePref) {
                case LIGHT_MODE: {
                    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
                    break;
                }
                case DARK_MODE: {
                    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
                    break;
                }
                default: {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
                    } else {
                        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY);
                    }
                    break;
                }
            }
        }
    }

参数mode有以下几种模式:

浅色 - MODE_NIGHT_NO
深色 - MODE_NIGHT_YES
由省电模式设置 - MODE_NIGHT_AUTO_BATTERY
系统默认 - MODE_NIGHT_FOLLOW_SYSTEM

监听深色主题是否开启

我们还可以监听到暗黑的主题是否开启
(1)在清单文件中给对应的Activity配置 android:configChanges=“uiMode”:

<activity android:name=".MainActivity"
            android:configChanges="uiMode">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
</activity>

(2)在onConfigurationChanged方法中获取:

@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        int currentNightMode = newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK;
        switch (currentNightMode) {
            case Configuration.UI_MODE_NIGHT_NO:
                Log.e("=======","=====关闭夜间模式====");
                // 关闭
                break;
            case Configuration.UI_MODE_NIGHT_YES:
                Log.e("=======","=====开启夜间模式====");
                // 开启
                break;
            default:
                break;
        }
}

这时,可以通过系统的设置切换暗黑模式的关闭和开启,查看下输出的Log。

判断深色主题是否开启

我们还可以判断深色模式是否开启:

public static boolean isNightMode(Context context) {
        int currentNightMode = context.getResources().getConfiguration().uiMode &
                Configuration.UI_MODE_NIGHT_MASK;
        return currentNightMode == Configuration.UI_MODE_NIGHT_YES;
}

结语

Android 10新加了暗黑模式,我们可以通过Force Dark来自动适配,然后再通过手动适配来进行图片资源以及颜色等的适配。

你可能感兴趣的:(小功能)