我想让用户在几个不同的主题之间进行选择,并且想知道这是否是一种正确的处理方式。我对此方法进行了一些测试,它确实有效,但是我认为可能会有更好的方法,并且以后可能会引起一些问题,因此想问一下。

我当时正在考虑为每个主题创建不同的布局,而在onCreate中只是为setContentView()方法设置了一个开关。我首先加载一个保存的SharedPreference值(整数),然后根据该值显示相应的布局来加载。显然,用户可以使用按钮或其他方式更改SharedPreference值。

由于这些布局基本上是相同的,但是具有不同的颜色,所以我想对每个布局文件中的TextViews和其他 View 使用相同的ID。我的主要问题是这会引起问题吗?

很抱歉,没有代码的文字墙。我只想对这种情况有一个良好实践的一般想法。提前致谢。

最佳答案

实际上,我的应用程序中具有此功能,此外,我还允许用户在运行时更改主题。由于从首选项中读取值需要花费一些时间,因此我通过保存缓存值的全局可访问函数获取主题ID。

正如已经指出的那样-使用this guide创建一些Android主题。 <style>文件中至少有两个styles.xml项。例如:

<style name="Theme.App.Light" parent="@style/Theme.Light">...</style>
<style name="Theme.App.Dark" parent="@style/Theme">...</style>

现在,您必须将其中一种样式应用于您的 Activity 。在执行其他任何调用之前,我正在activitie的onCreate方法中执行此操作:
setTheme(MyApplication.getThemeId());
getThemeId是一种返回缓存的主题ID的方法:
public static int getThemeId()
{
    return themeId;
}

此字段正在通过另一种方法更新:
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。首选项更改侦听器在本文结尾处描述,位于主要 Activity 类中。

最后一件非常重要的事情-在 Activity 开始时应用主题。假设您只能在首选项屏幕中更改主题,并且只有一种到达目的地的方式,即仅通过一个(主) Activity ,当您退出首选项屏幕时,该 Activity 将不会重新启动-旧主题仍然会用过的。解决方法如下(重新开始您的主要 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是一个 bool(boolean) 变量,最初设置为false。当此侦听器更改主题时,它将设置为true,这还将更新前面提到的缓存主题ID:
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);

请记住要保留对侦听器对象的引用,否则它将被垃圾回收(并且将停止工作)。

07-27 20:42
查看更多