官方介绍
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就是用来适配两种模式的。
项目中。
关于 drawable-night
(文件夹) 的创建方式:
右击 res文件夹 -> New -> Android Resource Directory,然后按下列截图进行操作
到了这里文件夹就已经创建完毕了,然后在文件夹创建文件即可
我这里把暗黑模式下首页的图标替换为了通讯录页的图标,效果如下:
values 和 value-night 文件夹
可以在这两个文件夹内创建你想要的文件比如color.用来普通模式和暗黑模式下的字体颜色,背景颜色。
创建方式很简单,右击valuest。 New-> Value Resoure File,然后填写的文件名称,例如 “font”。
然后同样的方式,右击values-nigh New-> Value Resoure File,创建一个font的文件夹。
然后填写上你需要的颜色就行了,但是记得 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项目下
按上面的步骤创建一个 Not Night 和 Night,创建成功后,系统会自动生成一个文件夹,如下。每个的作用模式后面有标识。
代码实践
要实现手动切换 night 和 notnight (思路来自于网络,忘了具体哪篇文章了)
1.添加 night和notnight 两种模式下的背景和字体颜色
2.添加 night和notnight 两种模式下的图标。
2.1、添加night模式下的图标就要创建drawable-night
文件夹。
找到下图中的文件夹
右击res 然后New -> Android Resource Dicectory,在弹出的窗口里面文件名称一定要
选择Night 然后点击Ok即可。
2.2、添加图标进 drawable
和 drawable-night
添加图标进drawable
去阿里巴巴矢量图库随便找一个图标 下载格式为.svg (因为svg可以自定义颜色)
Project下 -> 找到drawable右击 -> New -> Vector Asset
点击文件夹选择你下载的.svg图标,然后 Next
点击Finish
接下来,就可以在文件里面定义图标各部分颜色
添加图标进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
选择 Not Night,
再以同样的方式创建一个类型是 Night 的 shape
文件。成功之后你看到这样一个文件夹:
里面配置如下
(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) } //需要调用该方法才能生效
}
}
完成效果如下:
安卓的两种模式适配,学起来比较费劲,但是用起来还是挺简单的。