Android夜间模式动态切换不闪屏
夜间模式在一些资讯类app中是不可缺少的,通过查阅资料发现Android官方在Support Library 23.2.0中已经加入了夜间主题。也就是只需要通过更换主题便可实现日间模式和夜间模式的切换。下面截取项目实现的夜间模式效果图:
实现夜间模式需要的配置
1.配置gradle
implementation 'com.android.support:appcompat-v7:26.1.0'
2.添加夜间颜色资源文件
其中 colors.xml
<color name="colorPrimary">#FFFFFF</color>
<color name="colorPrimaryDark">#ffe0e0e0</color>
<color name="colorAccent">#03A9F4</color>
<color name="colorBaseBackground">#fafafa</color>
<color name="colorNavItemUnselected">#757575</color>
<color name="colorNavItemSelected">@color/colorAccent</color>
<color name="colorPrimaryText">#212121</color>
<color name="colorSecondaryText">#757575</color>
values-night 夜间文件夹 切换的时候系统会自己去找这个文件夹
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#35464e</color>
<color name="colorPrimaryDark">#212a2f</color>
<color name="colorAccent">#03A9F4</color>
<color name="colorPrimaryText">#e4e4e4</color>
<color name="colorSecondaryText">#b5b5b5</color>
<color name="colorBaseBackground">#212a2f</color>
<color name="colorNavItemSelected">#03A9F4</color>
<color name="colorNavItemUnselected">#8799a5</color>
</resources>
切换逻辑实现 这里需要介绍一下有关夜间模式的几个常量值。AppCompatDelegate.setDefaultNightMode(mode),其中mode有一下四个值:
MODE_NIGHT_NO: 亮色(light)主题,不使用夜间模式
MODE_NIGHT_YES:暗色(dark)主题,使用夜间模式
MODE_NIGHT_AUTO:根据当前时间自动切换 亮色(light)/暗色(dark)主题(22:00-07:00时间段内自动切换为夜间模式)
MODE_NIGHT_FOLLOW_SYSTEM(默认选项):设置为跟随系统,通常为MODE_NIGHT_NO
2.接下来需要我们在设置页面点击ToggleButton时切换白天/夜间模式。
具体实现如下:
/**
* Created by admin on 2018/11/1.
*/
public abstract class BaseActivity extends AppCompatActivity {
private boolean mNowMode;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View inflate = LayoutInflater.from(this).inflate(initView(), null);
setContentView(inflate); ;
mNowMode = SharedPreferencesUtil.getInstance().getBoolean(Constant.NIGHT);
initWidget(inflate);
if(savedInstanceState ==null){
initData();
}else{
restoreSavedInstanceState(savedInstanceState);
}
}
protected abstract void restoreSavedInstanceState(Bundle savedInstanceState);
protected abstract void initWidget(View inflate);
protected abstract void initData();
protected abstract int initView();
@Override
protected void onResume() {
super.onResume();
theme();
}
protected void theme() {
if (SharedPreferencesUtil.getInstance().getBoolean(Constant.NIGHT, false) != mNowMode) { //为了避免当 通过recreate重启activity造成死循环
if (SharedPreferencesUtil.getInstance().getBoolean(Constant.NIGHT, false)) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}
recreate();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}
创建 Main2Activity.java 去完成夜间模式 数据恢复
public class Main2Activity extends BaseActivity {
private ListView lv;
private CommonAdapter<String> adapter;
ArrayList<String> list = new ArrayList<>();;
@Override
protected void initWidget(View inflate) {
lv = findViewById(R.id.lv);
inflate.findViewById(R.id.tv).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (SharedPreferencesUtil.getInstance().getBoolean(Constant.NIGHT, false)) {
SharedPreferencesUtil.getInstance().putBoolean(Constant.NIGHT, false);
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
} else {
SharedPreferencesUtil.getInstance().putBoolean(Constant.NIGHT, true);
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
}
recreate();
}
});
adapter = new CommonAdapter<String>(this,list, R.layout.item) {
@Override
public void convert(ViewHolder holder, String s) {
TextView item_tv = holder.getView(R.id.item_tv);
item_tv.setText(s);
}
};
lv.setAdapter(adapter);
}
@Override
protected void initData() {
list.add("abc");
list.add("abc");
list.add("abc");
}
@Override
protected int initView() {
return R.layout.activity_main2;
}
/**
* 恢复数据
* @param savedInstanceState
*/
@Override
protected void restoreSavedInstanceState(Bundle savedInstanceState) {
list.addAll(savedInstanceState.getStringArrayList("list"));
adapter.notifyDataSetChanged();
}
/**
* recreate()方法会触发 这个保存数据方法
* @param outState
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putStringArrayList("list", list);
}
@Override
protected void onResume() {
super.onResume();
}
}
activity_main2.XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.roy.admin.themedemo.Main2Activity">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="黑夜切换"
android:textSize="20sp"
android:textColor="@color/colorPrimaryText"
android:layout_centerInParent="true"
/>
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/tv"
>
</ListView>
</RelativeLayout>
最后奉上demo地址:https://download.****.net/download/cly19940419/10759100