夜间模式实践(一)
为什么说是实践一呢? 因为这次写的只是实现夜间模式最基本的方式,当然会有一些瑕疵。
因为最近手机和电脑的模拟器一起抽风……就不给大家看效果了,就是跟知乎或者知乎日报的夜间模式差不多
直接上代码:
首先添加依赖:
compile ‘com.android.support:appcompat-v7:23.3.0’
配置相应的模式
<style name="AppTheme" parent="AppTheme.NoActionBar">
<!--状态栏颜色-->
<item name="colorPrimaryDark">@color/colorMain</item>
<!--Toolbar颜色-->
<item name="colorPrimary">@color/colorMain</item>
<!--返回键样式-->
<item name="drawerArrowStyle">@style/AppTheme.DrawerArrowToggle</item>
</style>
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.DayNight">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
因为我设置了NoActionBar 所以只要继承Theme.AppCompat.DayNight就好了。
然户在application节点设置
android:theme="@style/AppTheme"
- 设置夜间/白天模式的资源
主要是color和string
在res下新建一个values-night文件夹,然后新建colors.xml和strings.xml
设置相应的颜色和字符资源 比如:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#222222</color>
<color name="colorPrimaryDark">#2B2B2B</color>
<color name="colorAccent">#EDEDED</color>
<color name="colorMain">#222222</color>
<color name="colorGray">#8D8D8D</color>
<color name="colorBlack">#2B2B2B</color>
<color name="colorGrayWhite">#222222</color>
<color name="colorBG">#343434</color>
<color name="colorItemBG">#404040</color>
<color name="colorWord">#DDDDDD</color>
</resources>
注意: 这里所有的name必须和values目录下的colors.xml里的相同,在切换到夜间模式后才能正确的切换资源。
- 模式切换:
private void reSetMode() {
boolean isNightMode = PrefUtils.getBoolean(MainActivity.this, "isNightMode", false);
if (isNightMode) {
PrefUtils.setBoolean(MainActivity.this,"isNightMode",false);
getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO);
} else {
PrefUtils.setBoolean(MainActivity.this,"isNightMode",true);
getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES);
}
recreate();
}
解释一下 我在SharePreference中保存了一个值来标记当前是夜间模式还是白天模式 (PrefUtils是一个工具类就是操作SharePreference 大家不用在意)
MODE_NIGHT_NO: 不使用夜间模式
MODE_NIGHT_YES:使用夜间模式
MODE_NIGHT_AUTO:根据当前时间自动切换
MODE_NIGHT_FOLLOW_SYSTEM(默认):跟随系统,一般为MODE_NIGHT_NO
最后注意一定要recreate(); 不然是不会生效的,这也是这种方法算是一个不足的地方,因为在重启Activity时会有一瞬间的闪烁,效果就不好了。当然是有办法解决的,这里不做说明,之后会写,主要思想是保存一帧做透明度渐变
- 最后为了在关闭应用后再打开仍然保存之前的模式,需要在Application中做处理:新建一个MyApplication.java
public class MyApplication extends Application {
public static boolean isNightMode;
@Override
public void onCreate() {
super.onCreate();
isNightMode = PrefUtils.getBoolean(this.getApplicationContext(), "isNightMode", false);
if (isNightMode) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}
}
}
很简单 就是在启动的时候根据之前保存的标记变量来设置夜间/白天模式
在清单文件中
<application
android:name=".MyApplication"
基本上就是这样,看过很多方式来实现夜间模式,个人觉得这种是最好理解和实现的。当然有一点不足就是reCreate时候的一瞬间闪烁。后边介绍怎么解决这个问题。
有写的不对的地方 欢迎指正