android 夜间模式实现

最近项目需要需要实现 夜间模式功能,大致有两种实现方式:

  1. 设置日间、夜间两套theme,使用 setTheme 的方法让 Activity 设置主题;
  2. 通过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 方法重启页面。

猜你喜欢

转载自my.oschina.net/u/3729392/blog/1602499
今日推荐