Android黑白主题切换

使用Android原生的黑白主题切换方式实现,各应用需要准备两套资源文件,创建drawable-night,values-night等文件夹存放深色模式资源文件,资源文件名称,颜色名称等无需变化,与drawable,values下保持一致即可。实现方式有两种:

  1. 需要监听主题切换,需要在AndroidManifest的activity标签增加android:configChanges = “uiMode”,重写onConfigurationChanged方法,在onConfigurationChanged中处理切换主题后的逻辑,重新加载资源;
    监听onConfigurationChanged的方式如下:
@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    Log.d(TAG,"onConfigurationChanged");
    //todo
}
//此方式可以实现不重启切换主题,页面不是太多建议使用此方式。

2.不需要监听主题切换,则不需要增加android:configChanges = “uiMode”,切换主题后,应用会自动重启重新load资源,(若切换后应用未自动重启,尝试一下更新build.gradle中androidx.appcompat:appcompat的版本到1.4.0以上)。
注意:activity需要继承自AppCompatActivity!

  1. 监听onConfigurationChanged,收到主题变化通知后重启应用,执行
    public void reCreate(){
        finish();
        startActivity(new Intent( this, this.getClass()));
        overridePendingTransition(0, 0);
    }
//无退出动画下重启应用,重新加载资源文件。
<think> 在Android开发中,根据黑白主题(通常指深色模式和浅色模式)来配置ImageView的图片,可以通过资源限定符(如`-night`)来实现。以下是具体步骤: 1. **在`res`目录下创建对应的资源文件夹**: - 浅色主题的图片放在`drawable`或`mipmap`目录中。 - 深色主题的图片放在`drawable-night`或`mipmap-night`目录中。 2. **在布局文件或代码中引用图片资源**: - 在布局文件中,直接使用`@drawable/图片名称`,系统会根据当前主题自动选择合适的图片。 3. **代码示例**: - 假设有两张图片:`ic_logo_light.png`(浅色主题)和`ic_logo_dark.png`(深色主题)。 - 将`ic_logo_light.png`放入`res/drawable`目录,将`ic_logo_dark.png`放入`res/drawable-night`目录。 - 在布局文件中使用`ImageView`: ```xml <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_logo" /> ``` - 注意:这里使用相同的资源名称(`ic_logo`),系统会自动根据主题选择正确的图片。 4. **在代码中动态切换**(如果需要): - 通常,系统会自动切换。但如果需要手动检查主题并设置图片,可以这样做: ```java int currentNightMode = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; if (currentNightMode == Configuration.UI_MODE_NIGHT_YES) { imageView.setImageResource(R.drawable.ic_logo_dark); } else { imageView.setImageResource(R.drawable.ic_logo_light); } ``` 5. **使用主题属性**(推荐): - 另一种方法是使用主题属性(`?attr/`)来引用图片,但这通常用于颜色或可绘制对象的主题化。例如,在XML中定义属性: ```xml <!-- 在res/values/attrs.xml中定义属性 --> <attr name="logoImage" format="reference" /> ``` - 然后在主题中设置: ```xml <!-- 浅色主题 --> <style name="AppTheme" parent="Theme.MaterialComponents.Light"> <item name="logoImage">@drawable/ic_logo_light</item> </style> <!-- 深色主题 --> <style name="AppTheme.Night" parent="Theme.MaterialComponents"> <item name="logoImage">@drawable/ic_logo_dark</item> </style> ``` - 在布局中使用: ```xml <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="?attr/logoImage" /> ``` 以上方法都可以实现根据主题切换图片,推荐使用第一种(资源目录限定符)或第二种(主题属性)方式。 §§相关问题§§1. 如何为Android应用的其他资源(如颜色、字符串)配置深色主题?2. 在代码中如何检测当前系统是否处于深色模式?3. 除了图片,还有哪些UI元素需要适配深色主题?4. 如何让应用的主题切换不跟随系统设置而由用户手动控制? </think> 在Android开发中,根据黑白主题深色/浅色模式)动态配置ImageView的图片资源,可通过以下方法实现: ### 方法1:资源限定符(推荐) 1. 在`res`目录创建不同主题的资源文件夹: - 浅色主题:`res/drawable/ic_logo.xml` - 深色主题:`res/drawable-night/ic_logo.xml` 2. 使用相同的资源ID引用: ```xml <ImageView android:id="@+id/logo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_logo" /> <!-- 自动适配主题 --> ``` ### 方法2:代码动态切换 ```kotlin val isDarkMode = (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) == UI_MODE_NIGHT_YES val imageRes = if (isDarkMode) R.drawable.logo_dark else R.drawable.logo_light imageView.setImageResource(imageRes) ``` ### 方法3:主题属性(XML) ```xml <!-- 在res/values/themes.xml中定义 --> <style name="AppTheme" parent="Theme.MaterialComponents"> <item name="logoDrawable">@drawable/logo_light</item> </style> <style name="AppTheme.Night" parent="AppTheme"> <item name="logoDrawable">@drawable/logo_dark</item> </style> <!-- 布局中使用 --> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="?attr/logoDrawable" /> ``` ### 方法4:VectorDrawable自动着色 ```xml <ImageView android:src="@drawable/ic_vector_logo" android:contentDescription="Logo" android:tint="?attr/colorOnSurface"/> <!-- 自动跟随文字颜色变化 --> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值