android - 实现用户选择主题

标签 android android-theme

我想让用户在几个不同的主题之间进行选择,并且想知道这是否是一种合适的做事方式。我用这个方法做了一个小测试,效果很好,但是我觉得可能有更好的方法,并且认为它以后可能会导致一些问题,所以想问一下。

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

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

抱歉,没有代码的文字墙。我只是想大致了解这种情况下的良好做法。提前致谢。

最佳答案

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

如前所述 - 创建一些 Android 主题,使用 this guide .您将至少有两个 <style>您的 styles.xml 中的项目文件。例如:

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

现在,您必须将其中一种样式应用于您的 Activity 。我在 Activity 的 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 变量,最初设置为 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);

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

关于android - 实现用户选择主题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8811594/

相关文章:

java - 安卓结构: Two classes for one activity

Android:自定义操作栏主题错误 -(未找到匹配的资源......)

java - 错误: No resource found that matches the given name (at 'theme' with value '@style/Theme.Sherlock' )

android - 为相同的小部件类型定义不同的主题样式

android - 在不同的导航图中多次使用相同的 fragment

android - 相机在 Android 设备上不工作

java - 如何在 Android 中从 .txt 文件读取阿拉伯文本

java - 单击链接时 Android WebView 打开 uTorrent 应用程序

android - 深色主题安卓应用

android - 为 Lollipop 之前的可绘制选择器设置主题