如何在代码中为整个应用程序设置主题,但不在Manifest中?

时间:2011-04-01 05:58:51

标签: android themes

我知道如何在清单中将主题设置为整个应用程序,但是如何以编程方式将主题设置为整个应用程序?我正在尝试这样做:getApplicationContext. setTheme(R.style.mytheme),但它不起作用。

我认为getApplicationContext应用程序的上下文,它可以设置整个应用程序主题。

6 个答案:

答案 0 :(得分:8)

我花了很多时间让它工作,现在我的应用程序有可选择的Light and Dark主题,甚至可以动态选择立即进入游戏,包括Prefs。 下面是我使用的资源,其中一些其他想法被注释掉了,我在一些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之前没有强制性的Manifest主题显示非常重要。

为了能够动态地重新启动应用程序,我会检查这是否是应用程序的启动/重启方式。

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);
}

希望这能让你开始。 问候, 约翰。

答案 1 :(得分:6)

setTheme之前致电super.onCreate(),类似于以下代码

  public void onCreate(Bundle icicle) {
           if(Utility.isThemed)
             setTheme(R.style.Mytheme);
           super.onCreate(icicle);
    .....
    .....
}

答案 2 :(得分:4)

setTheme中,文档说:

  

请注意,之前应该调用它   任何视图都在实例化中   上下文(例如在调用之前   setContentView(View)或inflate(int,   ViewGroup中))。

你有没有照顾过这个?

答案 3 :(得分:3)

除非使用Java代码修改清单文件,否则无法将其应用于Java中的整个应用程序。您想要应用主题的其他活动可能甚至没有运行,那么Android如何将主题应用于它们?退出并返回到您的程序后,所有更改都将丢失,您需要再次应用主题。

getApplicationContext会返回应用程序上下文 - 但仅仅因为方法需要Context并不意味着将ApplicationContext传递给它会突然影响整个应用程序。事实上,它通常不会,并且只会像使用正常的上下文一样工作。

相反,不同上下文的重要性在于它们在不同的时间内存在 - 活动上下文是通过活动创建和销毁的,但是当第一个应用程序组件在最后一个组件运行和销毁时会创建一个Application上下文被毁了。

答案 4 :(得分:1)

您可以创建BaseActivity。 在此活动中更改您的样式。 您所有的活动都继承自该活动。

答案 5 :(得分:0)

我对我的应用程序中的所有活动使用自定义活动。

然后我检查我继承活动的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);

}

// styles.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>