几种实现夜间模式的方式
1:修改theme,重启activity
使用时定义不同的主题,通过切换主题重启acticity的方式完成切换
优点:正儿八经的夜间模式,配色看着舒服
缺点:图片刺眼、闪屏
2:覆盖一定透明度的View
使用一个带黑色带透明度的View,盖在现有的activity上,效果类似你带上墨镜,看着太阳不刺眼。
优点:不用重启activity,不闪屏;加上透明度过渡动画,模式之间切换非常舒服,解决了1中,白底图片依旧刺眼的问题。
缺点:配色没变化,就算带上墨镜,白天依旧是白天。
3:使用动态换肤方案
一般借助于第三方库完成换肤,如:
github.com/hongyangAnd…
github.com/fengjundev/…
优点:不用重启activity,不闪屏;可以为程序提供多种皮肤方案不局限于夜间/白天模式。
缺点:在制作方面代价过大,侵入性较强,需要以来第三方库完成,可靠性不能得到保证。
4:使用 Support Library 23.2.0 DayNight主题实现
优点:Google自家产品,可靠性高,配置简单,省心省力,在仅仅需要实现夜间/日间模式的应用内强烈推荐。
缺点:不支持多皮肤切换算吗?貌似今天只谈夜间模式的实现……。
使用DayNight主题来实现夜间模式
对于前两种方式来说,从实现来说是不困难的但是对用户的体验在一定程度上是很不好的,一个需要重启activity,一个配色无法改变都是我们不推荐的。
当然第三种方式市面上也有比较成熟的第三方库来完成程序的换肤,但是对于单单需要夜间模式的应用来说未免有些大材小用了。
今天我们使用DayNight主题来实现换肤功能。
1.定义DayNight主题,及相关属性
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
可以在主题中定义一些颜色尺寸等属性,在vlaues的colors.xml 声明color属性。
#3F51B5
#303F9F
#FF4081
在res下面创建values-night文件夹,创建colors.xml声明color属性
#1f2023
#18181a
#FF4081
2.为程序设置初始模式
程序中进行主题的初始化。你需要调用 AppCompatDelegate.setDefaultNightMode() ,它有四个参数:
MODE_NIGHT_NO. 使用亮色(light)主题
MODE_NIGHT_YES. 使用暗色(dark)主题
MODE_NIGHT_AUTO. 根据当前时间自动切换 亮色(light)/暗色(dark)主题
MODE_NIGHT_FOLLOW_SYSTEM(默认选项). 设置为跟随系统,通常为 MODE_NIGHT_NO
如在Application中进行初始化:
public class MyApplication extends Application {
static {
AppCompatDelegate.setDefaultNightMode(
AppCompatDelegate.MODE_NIGHT_NO);
}
@Override
public void onCreate() {
super.onCreate();
}
}
3.在初始化时就切换夜间模式
public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
// Set the local night mode to some value
getDelegate().setLocalNightMode(
AppCompatDelegate.MODE_NIGHT_...);
// 调用 recreate() 使设置生效
recreate();
}
} }
4.如何获取当前主题的状态
int currentNightMode = getResources().getConfiguration().uiMode
& Configuration.UI_MODE_NIGHT_MASK;
case Configuration.UI_MODE_NIGHT_NO:
case Configuration.UI_MODE_NIGHT_YES:
case Configuration.UI_MODE_NIGHT_UNDEFINED:
可以通过上面面的几种状态来进行相应的操作如:
```
private void judeStatusOfDayNight() {
int currentNightMode = getResources().getConfiguration().uiMode
& Configuration.UI_MODE_NIGHT_MASK;
switch (currentNightMode) {
case Configuration.UI_MODE_NIGHT_NO:
getDelegate().setDefaultNightMode(
AppCompatDelegate.MODE_NIGHT_YES);
break;
case Configuration.UI_MODE_NIGHT_YES:
getDelegate().setDefaultNightMode(
AppCompatDelegate.MODE_NIGHT_NO);
break;
case Configuration.UI_MODE_NIGHT_UNDEFINED:
getDelegate().setDefaultNightMode(
AppCompatDelegate.MODE_NIGHT_AUTO);
break;
}
// 调用 recreate() 使设置生效
recreate();
}
效果如下:
后记
当然,这仅仅是一个简单的例子,如果涉及图片你需要创建drawable-night文件夹。
对于一些按钮的颜色背景都需要做相应的处理,当然处理起来还是很简单的。
那么现在为你的程序加上夜间模式吧。