轻松实现夜间模式切换和沉浸式状态栏

给大家分享一种实现夜间模式的方式,文字部分很少,代码比较简单,所以只做简单描述和使用步骤

第一步:
将应用默认主题样式更改为下边这个

Theme.AppCompat.DayNight.NoActionBar

第二步:
SharedPreferencesUtil:已经封装好的一个工具类,提供了判断当前的主题模式是否是夜间模式方法,以及添加UI模式的方法

通过SharedPreferences储存主题模式,sp文件默认的key是mode,储存的字段默认的key是mode_ui,当然可以根据实际情况自己修改,以免出现sp文件名冲突

public class SharedPreferencesUtil {

    /**
     * 添加ui模式
     */
    static void addModeUI(Context context, boolean bool) {
        SharedPreferences.Editor editor = context.getSharedPreferences("mode", Context.MODE_PRIVATE).edit();
        editor.putBoolean("mode_ui", bool);
        editor.commit();
    }


    /**
     * 是否是夜间模式
     */
    static int getNight(Context context) {
        boolean bool = context.getSharedPreferences("mode", Context.MODE_PRIVATE).getBoolean("mode_ui", false);
        return bool ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO;
    }

}

第三步:
UIModeUtil:这个工具类封装的两个方法是用来夜间模式切换和显示当前模式的。

主要逻辑就是获取当前应用的主题模式然后判断是普通模式或夜间模式,作相应的取反,设置模式就是直接调用activity的getDelegate().setLocalNightMode(mode);方法设置进行设置。

public class UIModeUtil {

    /**
     * 夜间模式切换
     */
    static void changeModeUI(AppCompatActivity activity) {
        int currentNightMode = activity.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
        if (currentNightMode == Configuration.UI_MODE_NIGHT_NO) {
            activity.getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES);
            SharedPreferencesUtil.addModeUI(activity.getBaseContext(), true);
        } else {
            activity.getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO);
            SharedPreferencesUtil.addModeUI(activity.getBaseContext(), false);
        }
    }


    /**
     * 显示当前的模式
     */
    static void showModeUI(AppCompatActivity activity, int mode) {
        activity.getDelegate().setLocalNightMode(mode);
    }
}

第四步:
最后就是使用了,在需要做切换夜间模式的activity中进行如下操作:

  • 视图创建成功后就直接在actiyity的onStart()方法中设置最后一次配置的主题模式
@Override
    protected void onStart() {
        super.onStart();
        int mode = SharedPreferencesUtil.getNight(this);
        UIModeUtil.showModeUI(this, mode);
    }
  • 如果API版本大于19的平台,则需要进行如下设置,否则导航栏和状态栏将不会跟随主题变化
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//状态栏
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);//导航栏
   }
  • 最后把activity代码拿出来:
public class ThemeActivity extends AppCompatActivity {

    private AppCompatActivity activity;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Switch mSwitch = findViewById(R.id.sw);
        activity = this;
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//状态栏
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);//导航栏
        }
        
        if (SharedPreferencesUtil.getNight(this) == AppCompatDelegate.MODE_NIGHT_YES) {
            mSwitch.setChecked(true);
        } else {
            mSwitch.setChecked(false);
        }

        mSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                UIModeUtil.changeModeUI(activity);
                recreate();//重新创建
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        int mode = SharedPreferencesUtil.getNight(this);
        UIModeUtil.showModeUI(this, mode);
    }
}
  • xml代码



    


你可能感兴趣的:(轻松实现夜间模式切换和沉浸式状态栏)