实现用户的主题的选择主题、用户

2023-09-12 01:31:23 作者:不朽的少年

我想给用户几个不同的主题之间的选择,并且想知道,这是做事情的好吗方式。我做了一个小测试,用这种方法,它的工作,但我觉得有可能是更好的方法,并认为这可能会导致以后一些问题,所以想问问。

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()方法。我会载入保存共享preference 值(整数)第一,这取决于该值是显示相应的布局。显然,用户可以通过按钮或一些修改共享preference 值。

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.

由于这些布局将基本相同,但不同的颜色,我想用相同的ID为我的 TextViews 并在每个布局文件中的其他意见。我的主要问题是,这会导致问题?

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?

抱歉文本的墙,没有code。我只是想获得良好的实践的总体思路为这种情况。先谢谢了。

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.

推荐答案

其实,我在我的应用程序这个功能,另外,我允许用户更改主题,在运行时。当读取preferences价值需要一段时间,我通过全球访问的功能,保持高速缓存的价值得到一个主题标识。

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;
}

这是被称为每当preferences被改变(与,在课程的启动)。这两种方法驻留在所有MyApplication 类,它扩展了应用程序。在preference变化监听器在这篇文章的末尾描述和位于主活动类。

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.

最后和pretty的重要的事情 - 主题被应用,在活动开始时。假设,你只能在preference屏幕和更改主题,只有一个办法到达那里,即从只有一个(主)的活动,该活动将不会重新启动时,你会退出preference屏幕 - 旧的主题还是将被使用。下面是该修复(重新启动您的主要活动):

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);

记住要保持一个对侦听器对象,否则就会被垃圾colleted(和将停止工作)。

Remember to hold a reference to the listener object, otherwise it will be garbage colleted (and will cease to work).