最近项目需要需要实现 夜间模式功能,大致有两种实现方式:
设置日间、夜间两套theme,使用 setTheme 的方法让 Activity 设置主题;
通过Android Support Library:appcompat 包 中的 UiMode 来支持日间/夜间模式的切换(v23之后才有日间、夜间模式)
方法一需要对原有所有布局文件进行修改,工作量巨大,不适应于目前我们这种已经做了很久的项目,所以决定用第二种方式,具体实现步骤如下:
一、添加依赖包:
compile 'com.android.support:appcompat-v7:24.2.1'
二 、在application 中初始化uimode 模式:
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
initThemeMode();
通过Sharedpreferences 记录上一次设置的模式
private void initThemeMode() {
if (!Constants.enableNightModel) return;
isNight = SharedpreferencesUtil.isNightMode(this);
if (isNight) {
//夜间模式
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
} else {
//白天模式
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}
}
供settingactivity 调用的设置日/夜模式方法
public void setTheme(AppCompatActivity activity, boolean mode,boolean recreate) {
if (!Constants.enableNightModel) return;
if (isNight == mode) {
return;
}
if (!mode) {
//白天模式
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
activity.getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO);
} else {
//白天模式
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
activity.getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES);
}
isNight = mode;
SharedpreferencesUtil.saveNightMode(this,isNight);
if (recreate){
activity.recreate();
}
}
三、设置日间、夜间模式对应的 color/ drawable
3.1 设置两套color
color 中的颜色值名称要相同
如 日间模式 T5代表白色
夜间模式T5代码 灰黑色
原布局文件中的颜色引用不用改动
注意: 比如有个颜色值
#FF3232
values中color含有A1, values-night中color中没有A1,日间夜间模式都能正常访问,夜间模式下会读取 日间模式中的颜色值
但反过来,values-night中color中有A1,values中color没有A1,夜间模式正常,日间模式崩溃
3.2设置 图片资源
将相应模式下的图片放入相应的文件夹下,图片名称要一致
四,设置页面中设置日、夜间模式
private void setNightMode(boolean nightMode) {
MyApplication.getInstance().setTheme(context, nightMode, false);
}
此方式仅对新打开页面有效,已打开的页面 需要调用 recreate 方法重启页面。