3

我有一个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一个设置,主题可以有两个值之一,暗或亮。用户选择一个,然后点击返回按钮。这会导致调用 的onCreate方法MainActivity,再次应用设置但不正确。

任何人?我觉得一旦主题被更改,SettingsFragment然后按下后退按钮,主题应该被应用,MainActivity但事实并非如此。大多数元素发生变化,但文本保持黑暗(从 Holo.Light 到 Holo.Dark)。

4

3 回答 3

2

我想我可以帮你解决这个问题。在过去的几个月里,我花了很多时间为我的应用程序做同样的事情。

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

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

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

finish();
startActivity(getIntent());

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

于 2013-07-23T19:04:40.760 回答
0

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

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

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

您可以使用意图附加/数据来管理使用先前填充的数据重新创建父活动。

于 2013-07-25T09:14:03.573 回答
0

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

如果两者都不起作用,请回答:当您将偏好设置为深色样式并完全关闭您的应用程序时,当您打开活动时,您的样式是否正常?applySetting()(在 `super.onCreate() 之前和之后检查这个)

于 2013-07-23T15:57:58.640 回答