</style>
</resources>
- 右击res目录 -> New -> Directory,创建一个values-night目录,然后右击values-night目录 -> New ->
Values resource file,创建一个colors-night.xml文件。接着在这个文件中指定深色主题下的颜色值,颜色的命名要与colors.xml相同。
--colors.xml
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
<color name="colorTextView">#000</color>
</resources>
--colors-night.xml
<resources>
<color name="colorPrimary">#303030</color>
<color name="colorPrimaryDark">#232323</color>
<color name="colorAccent">#008577</color>
<color name="colorTextView">#FFFFFF</color>
</resources>
- 为那些在切换为暗黑模式时,需要改变颜色的控件适配,这里我们以TextView为例。
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorTextView"
android:padding="10dp"
android:textSize="20sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
效果对比如下图。效果明显比自动适配好上不少,算是初步实现了对暗黑模式的适配。
<table><tbody><tr><td><center><img src="https://img-blog.csdnimg.cn/20200609233534416.png"></center></td><td><center><img src="https://img-blog.csdnimg.cn/20200610000019879.png"></center></td></tr></tbody></table>
[]( )手动切换暗黑模式
目前为止我们已经知道了如何适配暗黑模式,在完成适配之后,我们还需要为用户提供在运行时,切换主题的选项,切换的代码也很简单,在菜单监听中通过getDelegate().setLocalNightMode()来设置当前的模式。
@Override
public boolean onOptionsItemSelected(MenuItem mi){
if(mi.isCheckable()){
mi.setChecked(true);
}
switch (mi.getItemId()){
case R.id.mode_light:
getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO);
break;
case R.id.mode_dark:
getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES);
break;
case R.id.mode_system:
getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
break;
}
return true;
}
setLocalNightMode()方法接收一个mode参数,用于控制当前应用程序的夜间模式。mode参数主要有以下值可供选择:
-
MODE_NIGHT_FOLLOW_SYSTEM:默认模式,表示让当前应用程序跟随系统设置来决定使用浅色主题还是深色主题。
-
MODE_NIGHT_YES:脱离系统设置,强制让当前应用程序使用深色主题。
-
MODE_NIGHT_NO:脱离系统设置,强制让当前应用程序使用浅色主题
- MODE_NIGHT_AUTO_BATTERY:根据手机的电池状态来决定使用浅色主题还是深色主题,如果开启了节点模式,则使用深色主题。
需要注意的是,当调用setLocalNightMode()方法并成功切换主题时,应用程序中所有处于started状态的Activity都会被重新创建,那如果不想Activity重新创建Activity怎么切换主题呢?
这时候我们可以在AndroidManifest中将configChanges设置为uiMode,使当前的Activity避免被重新创建。
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:configChanges="uiMode"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
现在当应用程序的主题发生变化时,MainActivity并不会重新创建,而是会触发onConfigurationChanged()方法的回调,你可以在回调当中手动做一些逻辑处理。
override fun onConfigurationChanged(newConfig: Configuration) {
val currentNightMode = newConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK
最后
最后这里放上我这段时间复习的资料,这个资料也是偶然一位朋友分享给我的,里面包含了腾讯、字节跳动、阿里、百度2019-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。
还有?高级架构技术进阶脑图、高级进阶架构资料?帮助大家学习提升进阶,也可以分享给身边好友一起学习。
一起互勉~