我正在尝试在我的应用程序上实现主题切换,我似乎无法刷新活动并将其设置为主题而无需重新启动整个活动(aka finish()+ startActivity())。
我尝试使findViewById(android.R.id.content)无效,但它不会刷新活动。改变方向会改变主题,因为再次调用onCreate。
那么像TweetLanes这样的应用程序如何实现此功能而无需重新启动应用程序/活动?
由于
答案 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
?也许我们的风格只需要修改一小部分内容?也许我们想要为特定值设置一些默认值?
那么如何申请呢?我们需要做几件事:
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 :(得分:1)
如果您想使用新主题重新启动活动,则必须完成它。
另外,如果您只想更改主题(如changig背景,颜色,按钮等等),那么您可以为您的应用制作自定义主题,然后根据特定操作应用该主题。
希望它会对你有所帮助。
答案 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);
}