第一种
一、依赖
compile 'com.android.support:appcompat-v7:26.1.0'
二、布局
<TextView android:id="@+id/yejian" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="夜间模式" />
三、属性设置
res下新建文件夹 values-night , values-night下新建 colors.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#3b3b3b</color> <color name="colorPrimaryDark">#383838</color> <color name="colorAccent">#a72b55</color> <color name="textColor">#FFFFFF</color> <color name="backgroundColor">#3b3b3b</color> </resources>
原values下colors
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#3F51B5</color> <color name="colorPrimaryDark">#303F9F</color> <color name="colorAccent">#FF4081</color> <color name="textColor">#FF000000</color> <color name="backgroundColor">#FFFFFF</color> </resources>
四、代码 MainActivity
import android.content.res.Configuration; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.app.AppCompatDelegate; import android.view.View; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private TextView yejian; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 默认设置为日间模式 AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); setContentView(R.layout.activity_main); yejian = (TextView) findViewById(R.id.yejian); yejian.setOnClickListener(new View.OnClickListener() { private int qiehuan; @Override public void onClick(View view) { int currentNightMode = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; getDelegate().setLocalNightMode(currentNightMode == Configuration.UI_MODE_NIGHT_NO ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO); recreate(); } }); } }
第二种
一、布局(不需要依赖)
<Button android:text="夜间模式" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btn_theme"/> <TextView android:text="用接口回调方法" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv" />
二、属性设置
values 下 colors.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#3F51B5</color> <color name="colorPrimary_night">#3b3b3b</color> <color name="colorPrimaryDark">#303F9F</color> <color name="colorPrimaryDark_night">#383838</color> <color name="colorAccent">#FF4081</color> <color name="colorAccent_night">#a72b55</color> <color name="textColor">#FF000000</color> <color name="textColor_night">#FFFFFF</color> <color name="backgroundColor">#FFFFFF</color> <color name="backgroundColor_night">#3b3b3b</color> </resources>
三、代码 ThemeManager
import android.content.Context; import android.content.res.Resources; import java.util.HashMap; import java.util.LinkedList; import java.util.List;
public class ThemeManager { // 默认是日间模式 private static ThemeMode mThemeMode = ThemeMode.DAY; // 主题模式监听器 private static List<OnThemeChangeListener> mThemeChangeListenerList = new LinkedList<>(); // 夜间资源的缓存,key : 资源类型, 值<key:资源名称, value:int值> private static HashMap<String, HashMap<String, Integer>> sCachedNightResrouces = new HashMap<>(); // 夜间模式资源的后缀,比如日件模式资源名为:R.color.activity_bg, 那么夜间模式就为 :R.color.activity_bg_night private static final String RESOURCE_SUFFIX = "_night"; /** * 主题模式,分为日间模式和夜间模式 */ public enum ThemeMode { DAY, NIGHT } /** * 设置主题模式 *@param themeMode */ public static void setThemeMode(ThemeMode themeMode) { if (mThemeMode != themeMode) { mThemeMode = themeMode; if (mThemeChangeListenerList.size() > 0) { for (OnThemeChangeListener listener : mThemeChangeListenerList) { listener.onThemeChanged(); } } } } /** * 根据传入的日间模式的resId得到相应主题的resId,注意:必须是日间模式的resId * @param dayResId 日间模式的resId * @return 相应主题的resId,若为日间模式,则得到dayResId;反之夜间模式得到nightResId */ public static int getCurrentThemeRes(Context context, int dayResId) { if (getThemeMode() == ThemeMode.DAY) { return dayResId; } // 资源名 String entryName = context.getResources().getResourceEntryName(dayResId); // 资源类型 String typeName = context.getResources().getResourceTypeName(dayResId); HashMap<String, Integer> cachedRes = sCachedNightResrouces.get(typeName); // 先从缓存中去取,如果有直接返回该id if (cachedRes == null) { cachedRes = new HashMap<>(); } Integer resId = cachedRes.get(entryName + RESOURCE_SUFFIX); if (resId != null && resId != 0) { return resId; } else { //如果缓存中没有再根据资源id去动态获取 try { // 通过资源名,资源类型,包名得到资源int值 int nightResId = context.getResources().getIdentifier(entryName + RESOURCE_SUFFIX, typeName, context.getPackageName()); // 放入缓存中 cachedRes.put(entryName + RESOURCE_SUFFIX, nightResId); sCachedNightResrouces.put(typeName, cachedRes); return nightResId; } catch (Resources.NotFoundException e) { e.printStackTrace(); } } return 0; } /** * 注册ThemeChangeListener * @param listener */ public static void registerThemeChangeListener(OnThemeChangeListener listener) { if (!mThemeChangeListenerList.contains(listener)) { mThemeChangeListenerList.add(listener); } } /** * 反注册ThemeChangeListener * @param listener */ public static void unregisterThemeChangeListener(OnThemeChangeListener listener) { if (mThemeChangeListenerList.contains(listener)) { mThemeChangeListenerList.remove(listener); } } /** * 得到主题模式 * @return */ public static ThemeMode getThemeMode() { return mThemeMode; } /** * 主题模式切换监听器 */ public interface OnThemeChangeListener { /** * 主题切换时回调 */ void onThemeChanged(); } }
MainActivity
import android.graphics.drawable.ColorDrawable; import android.os.Build; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.view.Window; import android.widget.Button; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; public class MainActivity extends AppCompatActivity implements ThemeManager.OnThemeChangeListener { private TextView tv; private Button btn_theme; private LinearLayout relativeLayout; private ActionBar supportActionBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ThemeManager.registerThemeChangeListener(this); supportActionBar = getSupportActionBar(); btn_theme = (Button) findViewById(R.id.btn_theme); relativeLayout = (LinearLayout) findViewById(R.id.relativeLayout); tv = (TextView) findViewById(R.id.tv); btn_theme.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ThemeManager.setThemeMode(ThemeManager.getThemeMode() == ThemeManager.ThemeMode.DAY ? ThemeManager.ThemeMode.NIGHT : ThemeManager.ThemeMode.DAY); if (ThemeManager.getThemeMode()== ThemeManager.ThemeMode.NIGHT){ btn_theme.setText("日间模式"); }else{ btn_theme.setText("夜间模式"); } } }); } public void initTheme() { tv.setTextColor(getResources().getColor(ThemeManager.getCurrentThemeRes(MainActivity.this, R.color.textColor))); btn_theme.setTextColor(getResources().getColor(ThemeManager.getCurrentThemeRes(MainActivity.this, R.color.textColor))); relativeLayout.setBackgroundColor(getResources().getColor(ThemeManager.getCurrentThemeRes(MainActivity.this, R.color.backgroundColor))); // 设置标题栏颜色 if(supportActionBar != null){ supportActionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(ThemeManager.getCurrentThemeRes(MainActivity.this, R.color.colorPrimary)))); } // 设置状态栏颜色 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Window window = getWindow(); window.setStatusBarColor(getResources().getColor(ThemeManager.getCurrentThemeRes(MainActivity.this, R.color.colorPrimary))); } } @Override public void onThemeChanged() { initTheme(); } @Override protected void onDestroy() { super.onDestroy(); ThemeManager.unregisterThemeChangeListener(this); } }