Программное переключение темы для всего приложения?

Я пытаюсь получить выбранную пользователем тему и чувствую, что я разочаровывающе близок. Определение темы в AndroidManifest.xml работает как надо, но (насколько я могу судить) не может меняться в зависимости от настроек приложения:

<application 
    android:theme="@style/theme_sunshine" 
    android:icon="@drawable/icon" 
    android:label="@string/app_name">

В качестве альтернативы, его динамическая установка в каждом действии также работает:

someChosenTheme = PreferenceManager.getDefaultSharedPreferences(this).getString("themePreference", "theme_twilight");
setTheme(someOtherChosenTheme);

Но это выглядит беспорядочно, и я бы предпочел установить тему для всего приложения в одном месте. Моей первой мыслью было захватить контекст приложения, как только запустится моя основная активность, и сделать это там:

getApplicationContext().setTheme(R.style.theme_dummy);

Насколько я могу судить, это должно делает трюк, но на самом деле ничего не делает — все приложение имеет стиль Android по умолчанию. Верно ли вышеизложенное, и если да, могу ли я делать что-то еще глупое?

Я работаю на уровне API 3, если это имеет значение. Продвижение в правильном направлении приветствуется!

Похожий вопрос.


person Cheezmeister    schedule 11.01.2011    source источник


Ответы (2)


Создайте базовое действие для своего приложения и переопределите onCreate, чтобы задать тему. Выведите все остальные ваши действия из этой базовой деятельности.

Также проверьте этот учебник:

http://www.androidengineer.com/2010/06/using-themes-in-android-applications.html

person peter3    schedule 12.01.2011
comment
Это, по сути, то, что я делаю. Это все еще не идеально, так как нет множественного наследования, например. для пользовательской ListActivity, но неудобство незначительное. Очень полезный урок, хотя я его уже читал :) - person Cheezmeister; 13.01.2011
comment
У меня действительно есть BaseListActivity и Base(Generic)Activity в каждом приложении, которое я делаю. BaseListActivity имеет встроенную общую обработку CRUD (чтение, добавление, редактирование, удаление), поэтому очень легко создать новую активность списка и просто переопределить несколько методов. Конечно, если я добавлю MapActivity или TabActivity, мне также придется создать для них BaseXActivity. Иногда множественное наследование просто лучше :) - person peter3; 14.01.2011
comment
Таким образом, добавление setTheme для каждого действия перед вызовом setContentView действительно является правильным решением? разве нет единого системного решения? Кроме того, что происходит со всеми действиями, которые уже существуют? - person android developer; 06.04.2014
comment
Для активных действий просто вызывайте recreate() всякий раз, когда меняется тема. Мерцание уродливое, но нам придется с этим жить. - person Andrei Lupsa; 07.03.2016
comment
Отличная ссылка на учебник, которая помогает мне ответить на несвязанный вопрос, который я получил недавно. Где определены такие атрибуты, как ?actionBarSize, и как они работают :) - person Ralphilius; 23.03.2016
comment
Ссылка работает, но исходный код внутри не работает, так как выдает ошибку Dropbox. Поэтому нигде в статье нет ответа на главный вопрос, чтобы показать, как программно изменить тему. - person samman; 06.01.2021

Для этого может быть хорошее решение, но я не смог его найти, поэтому в итоге я создал небольшой статический вспомогательный метод во вспомогательном классе, который принимает Activity и в основном выполняет те две строки, которые вы написали. Конечно, это не идеально, но просто добавить одну короткую строку кода к каждому методу onCreate() в моем приложении было терпимо.

person EboMike    schedule 11.01.2011