实现用户对主题的选择 [英] Implementing user choice of theme
问题描述
我想让用户在几个不同的主题之间进行选择,并且想知道这是否是一种正确的做事方式.我用这个方法做了一点测试,确实有效,但我认为可能有更好的方法,并且认为它以后可能会导致一些问题,所以想问一下.
I want to give the user the choice between a few different themes, and was wondering if this is an alright way of doing things. I did a little test with this method and it worked, but I think there may be better ways and think it may cause some problems later on, so wanted to ask.
我想为每个主题创建一个不同的布局,而在 onCreate
中只是有一个 setContentView()
方法的开关.我会首先加载一个保存的 SharedPreference
值(整数),并根据该值显示相应的布局.显然,用户可以使用按钮或其他东西更改 SharedPreference
值.
I was thinking of creating a different layout for each theme, and in onCreate
just having a switch for the setContentView()
method. I'd load a saved SharedPreference
value (integer) first and depending on what that value was display the corresponding layout. Obviously the user could change the SharedPreference
value with a button or something.
由于这些布局基本相同但颜色不同,因此我想为每个布局文件中的 TextViews
和其他视图使用相同的 ID.我的主要问题是这会导致问题吗?
As these layouts would be basically the same but with different colours, I'd want to use the same IDs for my TextViews
and other Views in each layout file. My main question is would this cause problems?
抱歉没有代码的文字墙.我只想大致了解这种情况下的良好做法.提前致谢.
Sorry for the wall of text with no code. I'd just like to get a general idea of good practice for this situation. Thanks in advance.
推荐答案
我的应用程序中实际上有这个功能,此外,我允许用户在运行时更改主题.由于从首选项中读取值需要一些时间,因此我通过保存缓存值的全局可访问函数获取主题 ID.
I actually have this feature in my application and additionally, I allow users to change theme at runtime. As reading a value from preferences takes some time, I'm getting a theme id via globally accessible function which holds cached value.
正如已经指出的 - 创建一些 Android 主题,使用 本指南.您的 styles.xml
文件中至少有两个 项目.例如:
As already pointed out - create some Android themes, using this guide. You will have at least two <style>
items in your styles.xml
file. For example:
<style name="Theme.App.Light" parent="@style/Theme.Light">...</style>
<style name="Theme.App.Dark" parent="@style/Theme">...</style>
现在,您必须将其中一种样式应用到您的活动中.在任何其他调用之前,我在活动的 onCreate
方法中执行此操作:
Now, you have to apply one of these styles to your activities. I'm doing this in activitie's onCreate
method, before any other call:
setTheme(MyApplication.getThemeId());
getThemeId
是一个返回缓存主题 ID 的方法:
getThemeId
is a method which returns cached theme ID:
public static int getThemeId()
{
return themeId;
}
此字段正在通过另一种方法更新:
This field is being updated by another method:
public static void reloadTheme()
{
themeSetting = PreferenceManager.getDefaultSharedPreferences(context).getString("defaultTheme", "0");
if(themeSetting.equals("0"))
themeId = R.style.Theme_Light;
else
themeId = R.style.Theme_Dark;
}
每当首选项更改时都会调用它(当然,在启动时).这两个方法驻留在MyApplication
类中,该类扩展了Application
.首选项更改侦听器在本文末尾进行了描述,位于主活动类中.
Which is being called whenever preferences are changed (and, on startup of course). These two methods reside in MyApplication
class, which extends Application
. The preference change listener is described at the end of this post and resides in main activity class.
最后一个非常重要的事情 - 主题在活动开始时应用.假设您只能在首选项屏幕中更改主题并且只有一种方法可以到达那里,即只有一个(主要)活动,当您退出首选项屏幕时,该活动不会重新启动 - 旧主题仍然是用过的.这是对此的修复(重新启动您的主要活动):
The last and pretty important thing - theme is applied, when an activity starts. Assuming, you can change a theme only in preference screen and that there's only one way of getting there, i.e. from only one (main) activity, this activity won't be restarted when you will exit preference screen - the old theme still will be used. Here's the fix for that (restarts your main activity):
@Override
protected void onResume() {
super.onResume();
if(schduledRestart)
{
schduledRestart = false;
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
}
scheduledRestart
是一个布尔变量,最初设置为 false.当此侦听器更改主题时,它会设置为 true,这也会更新前面提到的缓存主题 ID:
scheduledRestart
is a boolean variable, initially set to false. It's set to true when theme is changed by this listener, which also updates cached theme ID mentioned before:
private class ThemeListener implements OnSharedPreferenceChangeListener{
@Override
public void onSharedPreferenceChanged(SharedPreferences spref, String key) {
if(key.equals("defaultTheme") && !spref.getString(key, "0").equals(MyApplication.getThemeSetting()))
{
MyApplication.reloadTheme();
schduledRestart = true;
}
}
sp = PreferenceManager.getDefaultSharedPreferences(this);
listener = new ThemeListener();
sp.registerOnSharedPreferenceChangeListener(listener);
记得持有对监听对象的引用,否则会被垃圾回收(并停止工作).
Remember to hold a reference to the listener object, otherwise it will be garbage colleted (and will cease to work).
这篇关于实现用户对主题的选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!