Android:如何动态刷新活动/设置主题

时间:2012-12-12 03:49:25

标签: android android-layout themes

我正在尝试在我的应用程序上实现主题切换,我似乎无法刷新活动并将其设置为主题而无需重新启动整个活动(aka finish()+ startActivity())。

我尝试使findViewById(android.R.id.content)无效,但它不会刷新活动。改变方向会改变主题,因为再次调用onCreate。

那么像TweetLanes这样的应用程序如何实现此功能而无需重新启动应用程序/活动?

由于

3 个答案:

答案 0 :(得分:6)

相当简单。

假设您有一个名为/res/values/app_themes.xml的资源文件。在此xml文件中,您可以定义应用程序样式。我们称之为appGeneralTheme,它应该或多或少看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="appGeneralTheme">
    <!- Ofc you would use meaningful names and a separate file for colours but it's not the point. Those could be even different drawables, different strings, any kind of value can be styled/themed-->
    <item name="foo">#FF0000</item>
    <item name="bar">#00FF00</item>
    <item name="baz">#0000FF</item>
</style>
</resources>

现在让我们定义用户可以更改的特定主题。我们可以通过几种方式实现这一目标:

  • 在同一个app_themes.xml文件
  • 全部在另一个文件中,例如:pickables_themes.xml
  • 每个都在一个单独的文件中:qux_theme.xml, quux_theme.xml

为了简单起见,我们将所有内容保存在一个位置,因此在app_themes.xml我们将添加修改过的主题:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="appGeneralTheme">
    <item name="foo">#FF0000</item>
    <item name="bar">#00FF00</item>
    <item name="baz">#0000FF</item>
    <!-- other items -->
</style>

<style name="quxTheme" parent="@style/appGeneralTheme">
    <item name="foo">#FF00FF</item>
    <item name="bar">#00FFFF</item>
    <item name="baz">#FFFF00</item>
</style>
<style name="quuxTheme" parent="@style/appGeneralTheme">
    <item name="foo">#FF0099</item>
    <item name="bar">#00AAFF</item>
    <item name="baz">#FF1100</item>
</style>
</resources>

为什么parent?也许我们的风格只需要修改一小部分内容?也许我们想要为特定值设置一些默认值?

那么如何申请呢?我们需要做几件事:

  1. 致电Context.getTheme().applyStyle(resId, force)。在Context中我们有一个很好的方法Context.getTheme()这个方法允许我们在Theme对象上应用特定的样式。 Theme.applyStyle(...)的描述应该让您了解可能性:
  2.   

    将新属性值放入主题中。

    1. 无论好坏,您都应该为活动上下文和应用程序上下文执行此样式应用程序。

    2. 您不需要杀死该活动,简单Activity.recreate()即可。现在开始变得有趣了。

    3. 根据应用的设计方式,一切都可能会闪烁。现在我们有多种方法: - 多项活动 - 单项活动 - 多个片段 - 没有碎片 - 等等等

      这对最终的事情有影响。我只能根据自己对单个活动+片段的经验告诉你,如果你有几个片段交易,你会像迪斯科那样Activity.recreate()屏幕闪烁。

      有一种解决方法(相当hack-ish)。您不能重新创建整个活动,而只能在最顶部的可见片段上FragmentTransaction.detach(Fragment).attach(Fragment).commit()。其他不可见的片段应该没问题。

      为什么这很有用:

      • 您不需要将这些项目(例如:foobarbaz)定义为appGeneralTheme的子项,您可以拥有这些项目在任何样式的其他地方定义(如果你应用它将覆盖的样式)
      • 您可以逐个应用多种交错项目来实现某些功能(根据其他逻辑隐藏或显示某些内容)

      适用于一般意义上的主题(颜色)以外的任何内容

答案 1 :(得分:1)

如果您想使用新主题重新启动活动,则必须完成它。

另外,如果您只想更改主题(如changig背景,颜色,按钮等等),那么您可以为您的应用制作自定义主题,然后根据特定操作应用该主题。

请参阅:this , and this`以供参考

希望它会对你有所帮助。

答案 2 :(得分:0)

1-主要活动单击事件写入:

public onClick(View v){
    finish();
    Intent intent = new Intent(this, <your_setting _activity>.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);}

2-开设置活动写:

@Override
public void onBackPressed() {
    Intent intent = new Intent(this, <your_main_activity>.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
}