最近项目需要需要实现 夜间模式功能,大致有两种实现方式:
- 设置日间、夜间两套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代码 灰黑色
原布局文件中的颜色引用不用改动
注意: 比如有个颜色值
<color name="A1">#FF3232</color>
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 方法重启页面。