我有一个扩展PreferenceActivity的活动。
我的主题:android:theme =“@ android:style / Theme.Light.NoTitleBar.Fullscreen”应用于清单文件中的应用程序级别。
除了“PreferenceCategory”的“PreferenceScreen”元素之外,所有内容都获得了所需的主题。它们仍然具有默认的黑色背景。简单来说,具有父首选项屏幕的主要首选项类别屏幕正在获取主题,但如果我点击任何首选项屏幕以转到其元素首选项(EditText等等),它们就不会获得主题... < / p>
任何想法为什么会发生这种情况?
结构或preferences.xml是这样的:
<PreferenceCategory>
<PreferenceScreen>
<EditTextPreference>
...
</EditTextPreference>
<EditTextPreference>
...
</EditTextPreference>
...
</PreferenceScreen>
<PreferenceScreen>
...
</PreferenceScreen>
</PreferenceCategory>
答案 0 :(得分:5)
最后我发现如何以编程方式更改主题“PreferenceActivity”(通过java代码)
改变主题只需这样:
@Override
public void onCreate(Bundle savedInstanceState) {
setTheme(R.style.Holo_Theme_Light);
super.onCreate(savedInstanceState);
}
始终在setTheme(R.style.yourtheme);
方法之前调用super.onCreate(savedInstanceState);
方法。通过这样做,它将产生如下所示的结果。
就是这样。
如果您在setTheme(R.style.yourtheme);
方法之后调用super.onCreate(savedInstanceState);
方法,则会产生如下所示的结果。
注意:嵌套的PreferenceScreen无法识别主题。要将主题应用于嵌套的PreferenceScreen,您必须为该嵌套的PreferenceScreen制作另一个PreferenceActivity,并在那里调用setTheme(R.style.yourtheme);
方法。
答案 1 :(得分:3)
这是早期Android版本中的一个错误(另请参阅http://code.google.com/p/android/issues/detail?id=4611)。
如果我没记错,所有Android 2.x版本的主题都没有正确应用于PreferenceActivity。解决这个问题的一种方法是自己设置调整颜色/字体等,但是bug报告的注释中也有一个解决方法。主题应该在Android 3.0及更高版本上正常运行。
答案 2 :(得分:2)
查看PreferenceScreen#showDialog(Bundle)
的来源,我们看到该对话框是使用通过mContext.getThemeResId()
获得的主题资源创建的,然后在ContextThemeWrapper
中使用。
这可以大大帮助我们,因为我们所要做的就是覆盖Activity中的getThemeResId()
方法(隐藏在公共API中),提供我们的自定义主题,子PreferenceScreen现在使用我们想要的任何自定义主题资源!
/**
* This is a hack to provide our own theme for the PreferenceScreen's dialog.
*
* @see android.preference.PreferenceScreen#showDialog(Bundle)
*/
// NOTE there is no @Override, even though it overrides the Activity method
public int getThemeResId() {
return R.style.Theme_MyApp_PreferenceScreen;
}
请注意,由于此方法使用@hide
进行注释,因此我们无法使用通常在此情况下使用的@Override
注释;我们也无法调用super.getThemeResId()
方法。如果你真的,真的希望能够有条件地覆盖它并调用超级实现作为后备,你将不得不使用Reflection来实现超级实现#s方法:
try {
((Object) this).getClass().getMethod("getThemeResId").invoke(this);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
答案 3 :(得分:1)
正如所有其他答案尝试使用java代码解决它一样,这就是我完全使用xml并且没有声明我自己的首选项类的方法。
首先,我从 here 复制了首选项的完整布局,并将所有"@+android:id/xyz"
更改为"@android:id/xyz"
。然后在我的样式文件中,我将新样式声明为:
<style name="preference">
<item name="android:layout">@layout/source_preference</item>
</style>
现在在AppTheme中,一个新的偏好条目:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:textColor">@drawable/text_selector</item>
<item name="android:preferenceStyle">@style/preference</item>
</style>
现在,为这个新布局设置所需的所有样式。 就是这样。
答案 4 :(得分:0)
@Override
public boolean onPreferenceTreeClick(final PreferenceScreen preferenceScreen, final Preference preference) {
// https://code.google.com/p/android/issues/detail?id=4611 comment #35
if (preference instanceof PreferenceScreen && ((PreferenceScreen) preference).getDialog() != null)
((PreferenceScreen) preference).getDialog().getWindow().getDecorView().setBackgroundColor(Color.parseColor("#ffffff"));
return super.onPreferenceTreeClick(preferenceScreen, preference);
}