今天繼續解決昨天的夜間模式問題,因爲我是純手寫Activity,因此本身想不出更好的解決方法,經過學習別人的,解決了問題。
java
package com.example.fooks;android
import android.content.Context;
import android.content.res.Resources;緩存
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;學習
public class ThemeManager {code
// 默認是日間模式 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(); }
}blog