【问题标题】:Android: How to I apply a theme to all the activities of application after selecting one from preferences?Android:从偏好中选择一个主题后,如何将主题应用于应用程序的所有活动?
【发布时间】:2014-12-01 15:05:37
【问题描述】:

我做了一个简单的应用程序,我想在从首选项中选择后更改应用程序的所有活动(包括设置活动)的主题,但主题在选择后不适用。我尝试添加一个 recreate() 但在尝试启动主要活动时陷入困境。现在,我添加了一个执行 recreate() 的菜单项,但我希望它在您离开设置活动后自动应用。

MainActivity.java:

@Override
protected void onCreate(Bundle savedInstanceState) {

    SharedPreferences getData = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
    String themeValues = getData.getString("theme_preference", "1");

    if (themeValues.equals("1")) {
        setTheme(R.style.Theme_Light);
    }

    if (themeValues.equals("2")) {
        setTheme(R.style.Theme_Dark);
    }

    if (themeValues.equals("3")) {
        setTheme(R.style.Theme_Red);
    }

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);
}

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (id == R.id.action_settings) {
            Intent i = new Intent("com.cyanoise.helloworld.SettingsActivity");
            startActivity(i);

        return true;
    }

    if (id == R.id.about_app) {
        startActivity(new Intent(MainActivity.this, AboutActivity.class));

        return true;
    }

    if (id == R.id.refresh_app) {
        recreate();

        return true;
    }

    if (id == R.id.exitapp) {
        finish();
    }

    return super.onOptionsItemSelected(item);
}

SettingsActivity.java:

public class SettingsActivity extends PreferenceActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        addPreferencesFromResource(R.xml.settings);
    }
}

非常感谢所有答案。

【问题讨论】:

  • @DerGolem 我看过那篇文章,但我不太了解那里的代码和答案。希望在这里有一个更清晰、更解释的答案。
  • 在合成中,直到每个Activity重新启动后,才会应用主题。

标签: android android-preferences android-theme


【解决方案1】:

为了在返回时在每个活动中应用一个新主题,但仍然只在必要时重新创建活动,我正在使用自写的BaseActivity,我的所有活动都继承自它。

onCreate() 中,每个活动的主题都设置并保存在字符串变量theme 中。通过记住每个活动的当前主题,您可以将其与来自 onResume() 的 SharedPreferences 中的新主题进行比较,每当用户转向此活动时。

这样,如果主题还不匹配,您只需要在恢复的活动上调用this.recreate(),以使每个活动都显示最新的主题。

public abstract class BaseActivity extends AppCompatActivity {

   String theme;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        theme = PreferenceManager.getDefaultSharedPreferences(this).getString(getString(R.string.prefsThemesList), getString(R.string.prefsThemesList_default));
        try {
            Field resourceField = R.style.class.getDeclaredField(theme);
            int resourceId = resourceField.getInt(resourceField);
            setTheme(resourceId);
        } catch (Exception e) {
            e.printStackTrace();
        }

        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onResume() {
        super.onResume();
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
        if (!theme.equals(prefs.getString(getString(R.string.prefsThemesList), " none "))) {
            this.recreate();
        }
    }
}

【讨论】:

    【解决方案2】:

    好的,所以我一直在玩,并找到了解决方法。我在 SettingsActivity 中添加了一个 onBackPressed() 以再次调出 MainActivity,它似乎可以工作,一旦退出设置活动就应用所选主题。

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        startActivity(new Intent(SettingsActivity.this, MainActivity.class));
    }
    

    至于将主题应用于我刚刚添加的所有活动

    SharedPreferences getData = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
        String themeValues = getData.getString("theme_preference", "1");
    
        if (themeValues.equals("1")) {
            setTheme(R.style.Theme_Light);
        }
    
        if (themeValues.equals("2")) {
            setTheme(R.style.Theme_Dark);
        }
    
        if (themeValues.equals("3")) {
            setTheme(R.style.Theme_Red);
        }
    

    到每个活动的每个 onCreate。

    【讨论】:

    • 一种更简洁的方法是创建一个抽象的基础活动,并以此扩展您的所有活动。然后,您可以在基类中执行主题逻辑。
    • 一条switch 语句在代码可读性方面优于多个if 语句。
    猜你喜欢
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多