我實際上在我的應用程序中有此功能,另外,我允許用戶在運行時更改主題。由於從首選項中讀取值需要一些時間,我通過全局可訪問的函數獲取主題ID,該函數保存緩存的值。
正如已經指出的 - 使用this guide創建一些Android主題。您的styles.xml
文件中至少有兩個<style>
項目。例如:
<style name="Theme.App.Light" parent="@style/Theme.Light">...</style>
<style name="Theme.App.Dark" parent="@style/Theme">...</style>
現在,您必須將其中一種樣式應用於您的活動。我在活動中的的onCreate
方法這樣做,任何其他調用之前:
setTheme(MyApplication.getThemeId());
getThemeId
是返回緩存主題ID的方法:
public static int getThemeId()
{
return themeId;
}
該領域正被另一個方法更新:
public static void reloadTheme()
{
themeSetting = PreferenceManager.getDefaultSharedPreferences(context).getString("defaultTheme", "0");
if(themeSetting.equals("0"))
themeId = R.style.Theme_Light;
else
themeId = R.style.Theme_Dark;
}
每當首選項被改變時(以及當然啓動時),都會調用它。這兩種方法存在於MyApplication
類中,該類擴展了Application
。首選項更改偵聽器在本文後面描述,並駐留在主活動類中。
最後一個也是非常重要的事情 - 主題適用於活動開始時。假設,只能在首選項屏幕上更改主題,並且只有一種方法可以實現,即只有一個(主要)活動,當您退出首選項屏幕時,此活動不會重新啓動 - 舊主題仍然會用過的。下面是該修復(重新啓動您的主要活動):
@Override
protected void onResume() {
super.onResume();
if(schduledRestart)
{
schduledRestart = false;
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
}
scheduledRestart
是一個布爾變量,最初設置爲false。它設置爲true時,主題是由這個監聽器,這也更新之前提到的緩存主題ID改爲:
private class themeListener implements OnSharedPreferenceChangeListener{
@Override
public void onSharedPreferenceChanged(SharedPreferences spref, String key) {
if(key.equals("defaultTheme") && !spref.getString(key, "0").equals(MyApplication.getThemeSetting()))
{
MyApplication.reloadTheme();
schduledRestart = true;
}
}
sp = PreferenceManager.getDefaultSharedPreferences(this);
listener = new themeListener();
sp.registerOnSharedPreferenceChangeListener(listener);
記住要堅持監聽對象的引用,否則會被垃圾colleted(和將停止工作)。
非常好的答案,非常感謝! – 2012-01-10 23:18:16
我以爲我可以在不擴展應用程序的情況下解決問題,但問題是getApplicationInfo()。theme不會更新,如果我執行getApplication()。setTheme(myThemeId)'...所以是的,你的方法是正確的。 – vault 2013-01-25 17:21:49
現在看起來有一個更簡單的重新開始活動的方法:'重新創建'(https://developer.android.com/reference/android/app/Activity.html#recreate%28%29)。 – BlueMonkMN 2018-01-27 17:45:59