夜间模式(黑夜模式)的简单实现

前言
Android 6.0以后系统提供了AppCompatDelegate用来实现夜间模式和日间模式的切换,AppCompatDelegate中存在以下几种模式:

AppCompatDelegate.MODE_NIGHT_YES:设置夜间模式

AppCompatDelegate.MODE_NIGHT_NO:设置日间模式

AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM:跟随系统设置决定是否设置夜间模式

AppCompatDelegate.MODE_NIGHT_AUTO:根据当前时间自动切换模式

实现夜间模式需要配置两套资源文件而且资源文件的命名要完全一致,后缀带-night的目录对应夜间模式,比如values对应日间模式,values-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

设置主题
首先设置应用主题为DayNight模式,如Theme.AppCompat.DayNight.DarkActionBar或者Theme.MaterialComponents.DayNight.DarkActionBar,如下:

<style name="Theme.NightModeDemo" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
    <!-- Primary brand color. -->
    <item name="colorPrimary">@color/purple_500</item>
    <item name="colorPrimaryVariant">@color/purple_700</item>
    <item name="colorOnPrimary">@color/white</item>
    <!-- Secondary brand color. -->
    <item name="colorSecondary">@color/teal_200</item>
    <item name="colorSecondaryVariant">@color/teal_700</item>
    <item name="colorOnSecondary">@color/black</item>
    <!-- Status bar color. -->
    <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
    <!-- Customize your theme here. -->
</style>

AndroidManifest配置application的android:theme:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/Theme.NightModeDemo">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

顺便说一下,现在在Android Studio 4.0以上新建的project已经默认主题样式为Theme.MaterialComponents.DayNight.DarkActionBar,同时已经配置了日间和夜间两套主题文件theme.xml。

配置颜色
src/main/res目录下新建values-night目录,在该目录下新建colors.xml,然后配置同一个颜色值在values/colors.xml和values-night/colors.xml、也就是日间模式和夜间模式下对应的取值,注意颜色值的命名要完全一样。

values/colors.xml取值如下:

<resources>
    <color name="black">#000000</color>
    <color name="white">#FFFFFF</color>
    <color name="window_background">#FFFFFF</color>
</resources>

values-night/colors.xml取值如下:

<resources>
    <color name="black">#FFFFFF</color>
    <color name="white">#000000</color>
    <color name="window_background">#000000</color>
</resources>


配置图片
src/main/res目录下新建mipmap-night-xhdpi目录,在mipmap-night-xhdpi和mipmap-xhdpi目录分别配置夜间和日间模式的两套图片,注意两张图片的命名要完全一样。以ic_pic为例,项目结构如下:

使用

在布局文件中使用配置好的颜色和图片:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/window_background"
    android:gravity="center"
    android:orientation="vertical"
    tools:context=".MainActivity">
 
    <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/black"
        android:textSize="15sp"
        tools:text="白天模式" />
 
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:src="@mipmap/ic_pic" />
 
</LinearLayout>

其中shape_btn_bg如下:

<?xml version="1.0" encoding="utf-8"?>
<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>

在代码中使用:

class MainActivity : AppCompatActivity() {
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initMode()
        modeTv.setOnClickListener {
            switchMode()
        }
    }
 
    private fun initMode() {
        when (AppCompatDelegate.getDefaultNightMode()) {
            AppCompatDelegate.MODE_NIGHT_NO -> {
                modeTv.text = "日间模式"
            }
            AppCompatDelegate.MODE_NIGHT_YES -> {
                modeTv.text = "夜间模式"
            }
            else -> {
                modeTv.text = "日间模式"
            }
        }
    }
 
    //切换夜间模式
    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)  //切换为日间间模式
            }
            else -> {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)  //切换为夜间模式
            }
        }
        recreate()  //需要调用该方法才能生效
    }
 
}

最后看一下效果:

源码地址 
————————————————
版权声明:本文为CSDN博主「xuzhb24」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xuzhb_blog/article/details/121415362

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值