2013-07-15 112 views
2

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

有人吗?我觉得一旦SettingsFragment中的主题被更改,然后按下后退按钮,主题应该应用于MainActivity,但事实并非如此。大多数元素都会改变,但文字保持黑暗(从Holo.Light到Holo.Dark)。

+0

到目前为止您尝试过的更多细节/代码会有所帮助。您是否明确定义了要更改的文本?你是怎么做到的? –

+0

请参阅我的编辑。 – shortspider

+0

我假设在某一时刻您正在完成该活动(并且您可能希望在PreferenceActivity中使用PreferenceFragment而不是普通的PreferenceFragment)?另外,文本的问题也是针对'ActionBar'还是只是视图(如果你使用的话)? – Luksprog

回答

2

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

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

但是,如果当你旋转你的活动正在正确的主题(因为它被摧毁和重建的方向变化),那么有没有什么错,你是如何设置的主题。相反,当你退出SettingsFragment时,我倾向于认为你错误地调用了onCreate()

你可以强迫你的活动重新本身是这样的:(我打赌它不是)

finish(); 
startActivity(getIntent()); 

请首先尝试在你的活动的onCreate()方法中设置断点,并确认是否它打出来的片段然后尝试上面的代码。

+0

我在上面的代码中添加了我称之为'setContentView'的地方。如果我打完电话并开始一项新活动,那么我是否会放弃我的背部堆栈? – shortspider

+0

你是对的,'onCreate()'在按下后退按钮时不会被调用。 – shortspider

+0

您可以使用Activity类的recreate()方法进行重新创建,而不是finish()和startActivity(getIntent()); –

0

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

如果它不工作没有,回答这个问题:当您设置首选项,以黑暗风格和完全关闭应用,当你打开你的活动,你的风格是好的? (前,后两者applySetting()检查该`super.onCreate())

+0

截至目前,如果您重新启动应用程序或旋转应用程序主题正确应用,我会尝试在'super.onCreate()'之前调用'applySettings()'并查看会发生什么。 – shortspider

0

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

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

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

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