如何在代码中而不是在清单中为整个应用程序设置主题?

发布于 2024-10-29 03:23:14 字数 344 浏览 1 评论 0原文

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

我认为getApplicationContextApplication's Context,它可以设置整个应用程序主题。

I know how to set theme to whole application in manifest,but how to set theme to whole application programmatically ? I am trying this: getApplicationContext.setTheme(R.style.mytheme), but it doesn't work.

I think the getApplicationContext is the Application's Context, which can set whole application theme.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

唱一曲作罢 2024-11-05 03:23:14

我花了很多时间让它工作,现在我的应用程序有可选择的浅色和深色主题,甚至可以动态选择立即生效,包括首选项。
下面是我使用的资源,以及我在某个时间玩过的一些其他想法的注释。

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

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

I spent a lot of time getting this to work and now my app has selectable Light and Dark themes which can even be selected dynamically coming immediately into play including Prefs.
Below is the resource I use with some other ideas commented out which I played with at some 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> 

The key item here is

<item name="android:windowDisablePreview">true</item>

and that took me a while to realize.
My app does some heavy lifting while starting so it was important to not have the mandatory Manifest theme showing before the one I set in onCreate.

To be able to restart the app dynamically I check if this was how the app was started/restarted like this.

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

In Preferences I do this.

SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
boolean useThemeLight = sp.getBoolean("useThemeLight", false);
if (useThemeLight) {
    this.setTheme(R.style.MyAppThemeLight);
} else {
    this.setTheme(R.style.MyAppThemeDark);
}

Hope this gets you started.
Regards,
John.

圈圈圆圆圈圈 2024-11-05 03:23:14

super.onCreate() 之前调用 setTheme 类似于下面的代码

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

Call setTheme before super.onCreate() similar to below code

  public void onCreate(Bundle icicle) {
           if(Utility.isThemed)
             setTheme(R.style.Mytheme);
           super.onCreate(icicle);
    .....
    .....
}
笑梦风尘 2024-11-05 03:23:14

setTheme,文档说:

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

你照顾好了吗?

In setTheme, the documentation says:

Note that this should be called before
any views are instantiated in the
Context (for example before calling
setContentView(View) or inflate(int,
ViewGroup)).

Have you taken care of that?

硪扪都還晓 2024-11-05 03:23:14

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

getApplicationContext 确实返回应用程序上下文 - 但仅仅因为方法采用 Context 并不意味着向其传递 ApplicationContext 会突然使其产生影响整个应用程序。事实上,一般来说它不会,并且会像使用普通上下文一样工作。

相反,不同上下文的重要性在于它们存在的时间不同 - 活动上下文随活动一起创建和销毁,但应用程序上下文在第一个应用程序组件运行时创建,并在最后一个组件销毁时销毁。

You can't apply it to a whole application from Java, unless you use Java code to modify the manifest file. The other activities you want to apply the theme to might not even be running so how would Android apply a theme to them? And after exiting and returning to your program all the changes would be lost and you'd need to apply the theme again.

getApplicationContext does return the application context - but just because a method takes a Context doesn't mean that passing it an ApplicationContext will suddenly make it affect the whole application. In fact in general it won't, and will just work as if you used a normal Context.

Rather the importance of the different contexts is that they are around for different amounts of time - an activity context is created and destroyed with the activity, but an Application context is created when the first application component runs and destroyed when the last component is destroyed.

囍笑 2024-11-05 03:23:14

您可以创建 BaseActivity。
在此活动中改变您的风格。
您的所有活动都继承自此活动。

You can create BaseActivity.
Change your style in this Activity.
All your activity inherit from this Activity.

拥抱影子 2024-11-05 03:23:14

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

然后我在继承的活动的 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>

I use a custom activity for all activities in my application.

Then I check a preference value in the onCreate of my inherited activity e.g.

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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文