android夜间模式的实现
项目中要用到夜间模式,今天我就来总结,我是怎么实现的吧
实现原理:我们把当前的主题存放在sp中,每当activity启动之前调用setTheme方法设置相应的主题,setTheme方法一定要在super.onCreate()方法之前执行。
(1)在values文件夹下, 分别写一套夜间模式下的布局(theme_dark.xml)
和白天模式下的布局(theme_light.xml),
theme_dark.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme_Night" >
<item name="username_double">@color/night_gray_1</item>
<item name="gray_1_double">@color/gray_1_night</item>
<item name="gray_3_double">@color/gray_3_night</item>
<item name="source_bg">@drawable/source_bg_night</item>
</style>
</resources>
theme_light.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme_Light" >
<item name="username_double">@color/light_gray_1</item>
<item name="gray_1_double">@color/light_gray_1</item>
<item name="gray_3_double">@color/gray_3</item>
<item name="source_bg">@drawable/source_bg_light</item>
</style>
</resources>
(2) 在values文件下新建一个theme_attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <attr name="username_double" format="color" /> <attr name="gray_1_double" format="color" /> <attr name="gray_3_double" format="color" /> <attr name="source_bg" format="reference" /> </resources>
前面3个是颜色属性,后面是一个drawable类型,分别和 theme_light.xml和theme_night一一对应。当然还可以是状态选择器,shape图形资源。
(3) 在activity中我们要在super.onCreate()方法之前调用setTheme()方法,由于项目中的每个activity都要调用该方法,所以我把这个方法放在BaseActivity中实现。
public class BaseActivity extends Activity {
protected int skin;
public Context mContext;
SharedPreferences sp;
@Override
protected void onCreate(Bundle savedInstanceState) {
setThemeMode(getSkinTypeValue());
super.onCreate(savedInstanceState);
Global.mContext = this;
this.mContext = this;
sp = getSharedPreferences("AppSkinType", Context.MODE_PRIVATE);
}
protected void setThemeMode(SkinType skinType) {
switch (skinType) {
case Light:
setTheme(R.style.AppTheme_Light);
break;
case Night:
setTheme(R.style.AppTheme_Night);
break;
default:
setTheme(R.style.AppTheme_Light);
break;
}
}
protected SkinType getSkinTypeValue() {
if (sp == null) {
sp = getSharedPreferences("AppSkinType", Context.MODE_PRIVATE);
}
int i = sp.getInt("AppSkinType", 0);
switch (i) {
case 0:
return SkinType.Light;
case 1:
return SkinType.Night;
default:
break;
}
return SkinType.Light;
}
protected void saveSkinValue(int skin) {
if (sp == null) {
sp = getSharedPreferences("AppSkinType", Context.MODE_PRIVATE);
}
Editor editor = sp.edit();
editor.putInt("AppSkinTypeValue", skin);
editor.commit();
}
}
(4)下面是我写的一个列子,布局很简单,就是一个textView和chebox,checkBox选中的时候便设置成夜间模式,没有选中便为白天模式
代码如下:
package com.example.activity;
import com.example.night_mode.R;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
public class MainActivity extends BaseActivity {
private CheckBox cbSetting;
private String Tag = "mainActivity";
private Button btnForward;
private View llNight;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
llNight = findViewById(R.id.ll_night);
btnForward = (Button) findViewById(R.id.forward);
cbSetting = (CheckBox) findViewById(R.id.cb_setting);
cbSetting.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (cbSetting.isChecked()) {
// 设置夜间模式
saveSkinValue(1);
llNight.setBackgroundDrawable(getResources().getDrawable(R.drawable.source_bg_night));
} else {
// 设置白天模式
saveSkinValue(0);
llNight.setBackgroundDrawable(getResources().getDrawable(R.drawable.source_bg_light));
}
}
});
btnForward.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,
SecondActivity.class);
startActivity(intent);
}
});
}
}
代码已贴出