日夜间模式切换
1. 修改主题为 DayNight
将 styles.xml
中的主题改为 Theme.MaterialComponents.DayNight.NoActionBar
:
<!-- res/values/styles.xml -->
<resources>
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- 自定义主题属性 -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryVariant">@color/colorPrimaryDark</item>
<item name="colorOnPrimary">@color/colorOnPrimary</item>
<item name="colorSecondary">@color/colorSecondary</item>
<item name="colorSecondaryVariant">@color/colorSecondaryDark</item>
<item name="colorOnSecondary">@color/colorOnSecondary</item>
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
<item name="android:navigationBarColor">?attr/colorPrimaryVariant</item>
</style>
</resources>
2. 配置日间/夜间模式的资源文件
为了支持日间/夜间模式,你需要在 res
目录下创建不同的资源文件夹:
-
res/values/colors.xml
:默认颜色资源(日间模式)。 -
res/values-night/colors.xml
:夜间模式的颜色资源。
<!-- res/values/colors.xml (日间模式) -->
<resources>
<color name="colorPrimary">#6200EE</color>
<color name="colorPrimaryDark">#3700B3</color>
<color name="colorOnPrimary">#FFFFFF</color>
<color name="colorSecondary">#03DAC6</color>
<color name="colorSecondaryDark">#018786</color>
<color name="colorOnSecondary">#000000</color>
<color name="background">#FFFFFF</color>
<color name="textColor">#000000</color>
</resources>
<!-- res/values-night/colors.xml (夜间模式) -->
<resources>
<color name="colorPrimary">#BB86FC</color>
<color name="colorPrimaryDark">#3700B3</color>
<color name="colorOnPrimary">#000000</color>
<color name="colorSecondary">#03DAC6</color>
<color name="colorSecondaryDark">#018786</color>
<color name="colorOnSecondary">#000000</color>
<color name="background">#121212</color>
<color name="textColor">#FFFFFF</color>
</resources>
3. 在布局中使用颜色资源
在布局文件中使用颜色资源,而不是硬编码颜色值。例如:
<!-- res/layout/activity_main.xml -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="?attr/colorBackground">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, World!"
android:textColor="?attr/colorOnBackground" />
</LinearLayout>
4. 动态切换日间/夜间模式
你可以通过 AppCompatDelegate
动态切换日间/夜间模式。例如,在设置页面中添加一个切换按钮:
// 切换到夜间模式
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
// 切换到日间模式
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
// 跟随系统设置
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
在 Activity 中添加切换按钮
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val switchNightMode = findViewById<Switch>(R.id.switch_night_mode)
// 初始化按钮状态
when (AppCompatDelegate.getDefaultNightMode()) {
AppCompatDelegate.MODE_NIGHT_YES -> switchNightMode.isChecked = true
AppCompatDelegate.MODE_NIGHT_NO -> switchNightMode.isChecked = false
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM -> switchNightMode.isChecked = false
}
// 切换日间/夜间模式
switchNightMode.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
}
recreate() // 重启 Activity 以应用主题更改
}
}
}
5. 避免重启 Activity
如果你希望在不重启 Activity 的情况下切换日间/夜间模式,可以手动更新界面:
private fun updateUI() {
// 遍历视图树,更新所有文本内容
updateViewText(findViewById(android.R.id.content))
}
private fun updateViewText(view: View) {
when (view) {
is TextView -> {
// 根据视图的 ID 更新文本颜色
view.setTextColor(resources.getColor(R.color.textColor, theme))
}
is ViewGroup -> {
// 递归遍历子视图
for (i in 0 until view.childCount) {
updateViewText(view.getChildAt(i))
}
}
}
}