我正在尝试在我的应用程序上实现主题切换,但我似乎无法刷新活动并设置它们的主题,而无需重新启动整个活动(又名完成()+开始活动())。
我尝试使 findViewById(android.R.id.content) 无效,但它不会刷新活动。鉴于再次调用 onCreate ,改变方向会改变主题。
那么像 TweetLanes 这样的应用程序如何在无需重新启动应用程序/活动的情况下实现此功能呢?
谢谢
我正在尝试在我的应用程序上实现主题切换,但我似乎无法刷新活动并设置它们的主题,而无需重新启动整个活动(又名完成()+开始活动())。
我尝试使 findViewById(android.R.id.content) 无效,但它不会刷新活动。鉴于再次调用 onCreate ,改变方向会改变主题。
那么像 TweetLanes 这样的应用程序如何在无需重新启动应用程序/活动的情况下实现此功能呢?
谢谢
相当简单。
假设您有一个名为/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
?也许我们的样式只需要修改一小部分东西?也许我们想为特定值设置一些默认值?
那么如何应用呢?我们需要做几件事:
Context.getTheme().applyStyle(resId, force)
。在Context
我们有一个很好的方法Context.getTheme()这个方法允许我们在 Theme 对象上应用特定的样式。的描述Theme.applyStyle(...)
应该让您了解可能性:将新的属性值放入主题中。
无论好坏,您都应该为活动上下文和应用程序上下文执行这种风格的应用程序。
你不需要杀死活动,一个简单的Activity.recreate()就可以了。现在乐趣开始了。
一切都可能会闪烁,具体取决于您的应用程序的设计方式。现在我们有多种方法: - 多个活动 - 单个活动 - 多个片段 - 没有片段 - 等等等等
这对最终的事情有影响。我只能从我自己对单个活动 + 片段的经验告诉你,如果你有多个片段事务并且你会Activity.recreate()
像迪斯科一样闪烁屏幕。
有一种解决方法(相当hack-ish)。而不是重新创建整个活动,您只能FragmentTransaction.detach(Fragment).attach(Fragment).commit()
在最可见的片段上执行。其他不可见的片段应该没问题。
为什么这很有用:
foo
)bar
定义baz
为 的子样式appGeneralTheme
,您可以在任何样式的其他地方定义这些项目(如果您应用该样式,它将覆盖)适用于一般意义上的主题(颜色)以外的任何事物
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);
}