Как установить тему для всего приложения в коде, но не в Манифесте?

Я знаю, как установить тему для всего приложения в манифесте,но как установить тему для всего приложения программно ? Я пробую это: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>


<!--&lt;!&ndash;This is so that only the icon is showing in the intial theme&ndash;&gt;-->
    <!--&lt;!&ndash; ActionBar styles &ndash;&gt;-->
    <!--<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. Измените свой стиль в этой деятельности. Вся ваша деятельность наследуется от этой деятельности.