我有一个设置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)。
答案 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来管理使用先前填充的数据重新创建父活动。