1

我正在尝试在我的应用程序上实现主题切换,但我似乎无法刷新活动并设置它们的主题,而无需重新启动整个活动(又名完成()+开始活动())。

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

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

谢谢

4

3 回答 3

8

相当简单。

假设您有一个名为/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(...)应该让您了解可能性:

将新的属性值放入主题中。

  1. 无论好坏,您都应该为活动上下文和应用程序上下文执行这种风格的应用程序。

  2. 你不需要杀死活动,一个简单的Activity.recreate()就可以了。现在乐趣开始了。

一切都可能会闪烁,具体取决于您的应用程序的设计方式。现在我们有多种方法: - 多个活动 - 单个活动 - 多个片段 - 没有片段 - 等等等等

这对最终的事情有影响。我只能从我自己对单个活动 + 片段的经验告诉你,如果你有多个片段事务并且你会Activity.recreate()像迪斯科一样闪烁屏幕。

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

为什么这很有用:

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

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

于 2018-04-20T07:31:36.617 回答
1

如果你想用新主题重新开始活动,那么你必须完成它。

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

见:this , andthis`供参考

希望它会帮助你。

于 2012-12-12T04:06:21.517 回答
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);
}
于 2015-08-11T04:55:56.057 回答