安卓深色模式适配。

3,429 阅读4分钟

官方介绍

Android 10 (API 级别 29) 及更高版本中提供深色主题背景。深色主题背景具有诸多优势:

  • 可大幅减少耗电量(具体取决于设备的屏幕技术)。
  • 为弱视以及对强光敏感的用户提高可视性。
  • 让所有人都可以在光线较暗的环境中更轻松地使用设备。

深色主题背景同时适用于 Android 系统界面和在设备上运行的应用。

在 Android 10 (API 级别 29) 及更高版本中,您可以通过以下三种方法启用深色主题背景:

  • 使用系统设置(Settings -> Display -> Theme)启用深色主题背景。
  • 使用“快捷设置”图块,从通知托盘中切换主题背景(启用后)。
  • 在 Pixel 设备上,选择“省电模式”将同时启用深色主题背景。其他原始设备制造商 (OEM) 不一定支持这种行为。

要做的工作

创建好夜间模式需要的文件夹/文件。

实现夜间模式需要配置两套资源文件而且资源文件的命名要完全一致,后缀带-night的目录对应夜间模式,系统会根据当前的模式自动加载对应的资源文件。

日间模式    夜间模式
values    values-night
drawable    drawable-night
drawable-xhdpi    drawable-night-xhdpi
mipmap-mdpi    mipmap-night-mdpi
mipmap-hdpi    mipmap-night-hdpi
mipmap-xhdpi    mipmap-night-xhdpi
mipmap-xxhdpi    mipmap-night-xxhdpi
mipmap-xxxhdpi    mipmap-night-xxxhdpi

图中的color.xml就是用来适配两种模式的。

image.png

项目中。

关于 drawable-night(文件夹) 的创建方式:

右击 res文件夹 -> New -> Android Resource Directory,然后按下列截图进行操作

image.png image.png

image.png

到了这里文件夹就已经创建完毕了,然后在文件夹创建文件即可

image.png

我这里把暗黑模式下首页的图标替换为了通讯录页的图标,效果如下:

1FCE5AD8E13BFBE98BCE4D5CC0EC80AE.jpg FDAAF0C3BC036685302394F83FB529F5.jpg

values 和 value-night 文件夹

可以在这两个文件夹内创建你想要的文件比如color.用来普通模式和暗黑模式下的字体颜色,背景颜色。

image.png

创建方式很简单,右击valuest。 New-> Value Resoure File,然后填写的文件名称,例如 “font”。

然后同样的方式,右击values-nigh New-> Value Resoure File,创建一个font的文件夹。

image.png

image.png

然后填写上你需要的颜色就行了,但是记得 values/colors.xml和values-night/colors.xml文件内的有同样的名称。

<resources>
    <color name="purple_200">#FFBB86FC</color>
    <color name="purple_500">#FF6200EE</color>
    <color name="purple_700">#FF3700B3</color>
    <color name="teal_200">#FF03DAC5</color>
    <color name="teal_700">#FF018786</color>
    <color name="black">#FF000000</color>
    <color name="white">#FFFFFFFF</color>
    <color name="red">#C8910A</color>
    <color name="mainColor">#18BA4D</color>
    <color name="gray">#868686</color>
    <color name="tabbatUnoSelectColor">#0E0E0E</color>
</resources>

关于colors文件还有第二种创建方式

Android项目下

image.png image.png image.png image.png

按上面的步骤创建一个 Not Night 和 Night,创建成功后,系统会自动生成一个文件夹,如下。每个的作用模式后面有标识。

image.png

代码实践

要实现手动切换 night 和 notnight (思路来自于网络,忘了具体哪篇文章了)

1.添加 night和notnight 两种模式下的背景和字体颜色

image.png

2.添加 night和notnight 两种模式下的图标。

2.1、添加night模式下的图标就要创建drawable-night文件夹。

找到下图中的文件夹

image.png

右击res 然后New -> Android Resource Dicectory,在弹出的窗口里面文件名称一定要

image.png image.png

选择Night 然后点击Ok即可。

image.png

2.2、添加图标进 drawabledrawable-night

添加图标进drawable

去阿里巴巴矢量图库随便找一个图标 下载格式为.svg (因为svg可以自定义颜色)

Project下 -> 找到drawable右击 -> New -> Vector Asset

image.png

点击文件夹选择你下载的.svg图标,然后 Next

image.png

点击Finish

image.png

接下来,就可以在文件里面定义图标各部分颜色

image.png
添加图标进drawable-night

添加图标的时候无法选择直接添加进drawable-night文件夹,但是可以添加到drawable的icon复制一份到drawable-night文件夹,在修改一下颜色即可。

编写一个布局代码 点击修改系统模式。

在你的布局页面添加如下代码

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/window_background"
    android:gravity="center"
    android:orientation="vertical">
    <TextView
        android:id="@+id/modeTv"
        android:layout_width="100dp"
        android:layout_height="50dp"
        android:background="@drawable/shape_btn_bg"

        android:gravity="center"
        android:textColor="@color/titleColor"
        android:textSize="15dp"
        android:text="白天模式"
        tools:text="白天模式"/>
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:src="@drawable/ic_wechar_icon" />

</LinearLayout>

这个样式文件shape_btn_bg需要新建,

步骤如下: Android -> 找到drawable右击 New -> Drawable Resource File

image.png image.png

选择 Not Night,

image.png

再以同样的方式创建一个类型是 Night 的 shape 文件。成功之后你看到这样一个文件夹:

image.png

里面配置如下

(Night)

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="6dp" />
    <stroke
        android:width="2dp"
        android:color="@color/white" />
    <solid android:color="@color/black" />
</shape>

(Not Night)

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="6dp" />
    <stroke
        android:width="2dp"
        android:color="@color/black" />
    <solid android:color="@color/white" />

</shape>

然后到 Fragment文件里编写代码,全部代码如下:

class WeChatFragment : Fragment() {

    companion object {
        fun newInstance() = WeChatFragment()
    }

    private lateinit var viewModel: WeChatViewModel

    var modeTv:TextView? = null

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        var view = inflater.inflate(R.layout.fragment_wechat, container, false)
        modeTv  = view.findViewById<TextView>(R.id.modeTv)
        initMode()
        modeTv?.setOnClickListener {
            switchMode()
        }
        return view
    }


    private fun initMode() {
        when (AppCompatDelegate.getDefaultNightMode()) {
            AppCompatDelegate.MODE_NIGHT_NO -> {
                modeTv?.text = "NotNight模式"
            }
            AppCompatDelegate.MODE_NIGHT_YES -> {
                modeTv?.text = "Night模式"
            }
            else -> {
                modeTv?.text = "NotNight模式"
            }
        }
    }

    //切换夜间模式
    private fun switchMode() {
        when (AppCompatDelegate.getDefaultNightMode()) {
            AppCompatDelegate.MODE_NIGHT_NO -> {  
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)  //切换为暗黑模式
            }
            AppCompatDelegate.MODE_NIGHT_YES -> {  
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)  //切换为NotNight模式
            }
            else -> {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)  //切换为暗黑模式
            }
        }
        activity?.let { recreate(it) }  //需要调用该方法才能生效
    }


}

完成效果如下:

dc1aw-o04vh.gif

安卓的两种模式适配,学起来比较费劲,但是用起来还是挺简单的。