从片段更改活动主题

时间:2013-07-15 16:44:47

标签: android android-preferences android-theme

我有一个设置PreferenceFragment,允许用户选择主题。用户可以选择黑暗或浅色主题。选择主题后,用户按下后退按钮返回上一个片段。这称为包含活动的onCreate方法,其中读取和应用主题。但是主题未正确应用,从Holo.Light切换到Holo.Dark会更改背景颜色,操作栏等,但不会更改文本,从而导致文本褪色,难以阅读。我有什么想法我做错了吗?我读过的所有内容都说应该在onCreate方法中应用主题,这就是我正在做的事情。

提前感谢您的帮助。

修改

这里要求的是相关代码。

public class MainActivity extends Activity {

     private ActionBarDrawerToggle mSlideMenuToggle;
     private boolean isDarkTheme;
     private static final String InitializedKey = "initialized";

     @Override
 protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
          applySettings();
          setContentView(R.layout.activity_main);
       }

     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
          if (mSlideMenuToggle.onOptionsItemSelected(item)) {
               return true;
          } else if (item.getItemId() == R.id.menu_settings) {
               getFragmentManager().beginTransaction()
                        .replace(R.id.content_frame, new SettingsFragment())
                        .addToBackStack(null)
                        .commit();
               return true;
          } else {
               return super.onOptionsItemSelected(item);
          }
     }

     private void applySettings() {
          isDarkTheme = PreferenceManager.getDefaultSharedPreferences(this).getString(SettingsFragment.ThemeSetting, null).equals("1");
          if (isDarkTheme) {
               setTheme(android.R.style.Theme_Holo);
          } else {
               setTheme(android.R.style.Theme_Holo_Light);
     }
}

onCreate方法通过调用applySettings将当前主题应用于活动。选项菜单允许创建SettingsFragment

public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {

   public static final String ThemeSetting = "isDarkTheme";

   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       addPreferencesFromResource(R.xml.preferences);
   }

   @Override
   public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
       if (key.equals(ThemeSetting)) {
           String[] themes = getResources().getStringArray(R.array.isDarkThemeStrings);
           findPreference(key).setSummary(sharedPreferences.getString(key, "").equals("0") ? themes[0] : themes[1]);
       }
   }

   @Override
   public void onResume() {
       super.onResume();
       PreferenceManager.getDefaultSharedPreferences(getActivity()).registerOnSharedPreferenceChangeListener(this);
   }

   @Override
   public void onPause() {
       super.onPause();
       PreferenceManager.getDefaultSharedPreferences(getActivity()).unregisterOnSharedPreferenceChangeListener(this);
   }

 }

SettingsFragment有一个设置,主题可以有两个值之一,Dark或Light。用户选择一个,然后点击后退按钮。这会导致调用onCreate的{​​{1}}方法,再次应用设置但不正确。

任何?我觉得,一旦主题在MainActivity中更改,然后按下后退按钮,主题应该应用于SettingsFragment,但事实并非如此。大多数元素都会发生变化但文字仍然很暗(从Holo.Light变为Holo.Dark)。

3 个答案:

答案 0 :(得分:2)

我想我可以帮助你。在过去的几个月里,我花了很多时间为我的应用程序完成同样的事情。

上面的海报并不完全正确。在实例化视图之前,您需要在onCreate()中设置主题 - 在setContentView()之前。调用super.onCreate()时并不重要。我在上面的代码中没有看到setContentView(),所以我想知道你是否删除了它?

但是,如果您的活动在旋转时正确主题(因为它在方向更改时被销毁并重新创建),那么您设置主题的方式没有任何问题。相反,当你退出SettingsFragment时,我倾向于认为你错误地调用了onCreate()

您可以强制您的活动像这样重新创建自己:

finish();
startActivity(getIntent());

请先尝试在您的活动的onCreate()方法中设置一个断点,并确认它是否在退出您的片段时被击中(我打赌不是。)然后尝试上面的代码。

答案 1 :(得分:0)

在super.onCreate()之前调用applySetting()

如果它不能正常工作,请回答:当您将首选项设置为黑暗风格并完全关闭应用程序时,当您打开活动时,您的风格是否合适? (在`super.onCreate())

之前和之后用applySetting()检查

答案 2 :(得分:0)

这里的问题是,除非您重新创建活动,否则不会应用主题。主题应用于onCreate()中setContentView方法调用之前的活动。当您向后导航时,您不是通过onCreate()方法重新输入,而是通过onResume()重新输入。

要解决此问题,更改主题首选项将意味着必须清除后台堆栈,否则主题将不会应用于后台堆栈中的活动。从可用性的角度来看,这种设置应该只能通过应用程序的顶级活动提供。

实施ThemeChangeListener并将其添加到您的活动中。当主题发生变化时,调用ThemeChangeListener并在任何打开的活动上调用finish()(除了您所在的页面)。然后在onBack()中手动重新创建用户使用Lisa提供的代码导航到设置页面的顶级活动。

您可以使用intent extras / data来管理使用先前填充的数据重新创建父活动。