Как установить тему для всего приложения в коде, но не в Манифесте?
Я знаю, как установить тему для всего приложения в манифесте,но как установить тему для всего приложения программно ? Я пробую это:getApplicationContext.
setTheme (R. style.мифема), но это не работает.
Я думаю getApplicationContext
это контекст приложения, который может установить всю тему.
6 ответов
вы не можете применить его ко всему приложению из Java, если вы не используете код Java для изменения файла манифеста. Другие действия, к которым вы хотите применить тему, могут даже не работать, так как Android применит к ним тему? И после выхода и возвращения в вашу программу все изменения будут потеряны, и вам нужно будет снова применить тему.
getApplicationContext
возвращает контекст приложения - но только потому, что метод принимает Context
не означает, что передача его ApplicationContext
внезапно повлияет на все приложение. На самом деле в целом это не будет, и будет просто работать, как если бы вы использовали Нормальный контекст.
скорее важность различных контекстов заключается в том, что они существуют в течение разных промежутков времени - контекст действия создается и уничтожается вместе с действием, но контекст приложения создается при запуске первого компонента приложения и уничтожается при уничтожении последнего компонента.
Я потратил много времени на то, чтобы это работало, и теперь мое приложение имеет выбираемые светлые и темные темы, которые даже могут быть выбраны динамически, немедленно вступая в игру, включая префы. Ниже-это ресурс я использую некоторые другие идеи закомментирован которые я играл в какой-то starge.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--The base theme ensures nothing is shown until the first activity. All activities and fragmenst must-->
<!--set a them in onCreate or in AndroidManifext or they wil crash because of no title.-->
<!--Using Theme.Holo.NoActionBar suppresses the ActionBar initially so Icon doesn't show until new theme is set.-->
<style name="MyAppThemeInitial" parent="@android:style/Theme.Holo">
<!--<item name="android:windowBackground">@color/initial_background_grey</item>-->
<!--<item name="android:actionBarStyle">@style/MyActionBar</item>-->
<item name="android:windowDisablePreview">true</item>
</style>
<style name="MyAppThemeDark" parent="@android:style/Theme.Holo">
<item name="android:windowBackground">@color/black</item>
</style>
<style name="MyAppThemeLight" parent="android:Theme.Holo.Light">
<item name="android:windowBackground">@color/white</item>
</style>
<!--<!–This is so that only the icon is showing in the intial theme–>-->
<!--<!– ActionBar styles –>-->
<!--<style name="MyActionBar" parent="@android:style/Widget.Holo.ActionBar">-->
<!--<item name="android:background">@android:color/transparent</item>-->
<!--<item name="android:titleTextStyle">@style/MyActionBarTextAppearance</item>-->
<!--</style>-->
<!--<style name="MyActionBarTextAppearance">-->
<!--<item name="android:textColor">@android:color/transparent</item>-->
<!--</style>-->
</resources>
ключевым элементом здесь является
<item name="android:windowDisablePreview">true</item>
и мне потребовалось некоторое время, чтобы понять. Мое приложение делает некоторые тяжелые подъемы во время запуска, поэтому было важно не иметь обязательного Манифест тема, показывающая перед тем, что я установил в onCreate.
чтобы иметь возможность динамически перезапускать приложение, я проверяю, было ли это так, как приложение было запущено/перезапущено.
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
boolean useThemeLight = sp.getBoolean("useThemeLight", false);
//Since this Activity can also be started by the Theme Toggle in the Action bar we need to see if
//there is a TOGGLE_THEME extra which only it uses
Intent curIntent = this.getIntent();
if (curIntent.getExtras() != null && curIntent.getExtras().containsKey(TOGGLE_THEME)) {
if(curIntent.getStringExtra(TOGGLE_THEME).equals("Dark")){
this.setTheme(R.style.MyAppThemeDark);
CurrentTheme = "Dark";
}else{
this.setTheme(R.style.MyAppThemeLight);
CurrentTheme = "Light";
}
activityThemeToggleActive = true;
} else {
if (useThemeLight) {
this.setTheme(R.style.MyAppThemeLight);
CurrentTheme = "Light";
} else {
this.setTheme(R.style.MyAppThemeDark);
CurrentTheme = "Dark";
}
}
в настройках я это делаю.
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
boolean useThemeLight = sp.getBoolean("useThemeLight", false);
if (useThemeLight) {
this.setTheme(R.style.MyAppThemeLight);
} else {
this.setTheme(R.style.MyAppThemeDark);
}
надеюсь, это поможет вам начать. С уважением, Джон.
вызов setTheme
до super.onCreate()
похожие на ниже code
public void onCreate(Bundle icicle) {
if(Utility.isThemed)
setTheme(R.style.Mytheme);
super.onCreate(icicle);
.....
.....
}
на setTheme, в документации сказано, что:
обратите внимание, что это должно быть вызвано раньше любые представления создаются в Контекст (например, перед вызовом setContentView (вид) или надуть(int, ViewGroup)).
вы позаботились об этом?
Я использую пользовательское действие для всех действий в моем приложении.
затем я проверяю значение предпочтения в onCreate моей унаследованной активности, например
public class MyCustomActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(this);
if(prefs.getBoolean("use_light_theme",false)==true)
{
setTheme(R.style.AppThemeLight);
}
super.onCreate(savedInstanceState);
}
//стили.в XML
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Holo">
<!-- Customize your theme here. -->
</style>
<style name="AppThemeLight" parent="android:Theme.Light">
<!-- Customize your theme here. -->
</style>
вы можете создать BaseActivity. Измените свой стиль в этой деятельности. Вся ваша деятельность наследуется от этой деятельности.