PreferenceActivity和主题不适用

大家好我已经在清单文件中设置了这样的主题

android:theme="@android:style/Theme.Light" 

但是我在首选项活动中遇到了一个问题,在主要首选项中主题显示正常,但是如果我得到一个子选项,主题变得杂乱,它不是白色,因为它应该是黑暗的,字体是黑色,所以你不能看到太多,当我开始点击任何项目时,他们有时会得到白色,但他们应该尽快恢复黑色。 这只发生在2.1,在真实的设备和模拟器。 在运行1.6的模拟器上testing过,并且工作正常。 以下是偏好xml文件的代码的一部分:

 <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceScreen android:title="@string/account"> <CheckBoxPreference android:key="enable_account" android:title="@string/account_use" android:summary="@string/account_summ" /> <EditTextPreference android:key="username" android:title="@string/login" android:dependency="enable_account" android:summary="@string/login_summ" /> <EditTextPreference android:key="password" android:title="@string/password" android:dependency="enable_account" android:summary="@string/password_summ" android:password="true" /> </PreferenceScreen> 

这里是一个截图:

替代文字http://sofzh.miximages.com/android/16hnhh3.png

任何解决方法?

Solutions Collecting From Web of "PreferenceActivity和主题不适用"

有人在http://code.google.com/p/android/issues/detail?id=4611上发布了一个解决方&#x6CD5;

简而言之,顶级的首选项屏幕似乎认可主题,但嵌套的主题不是。 因此,解决方法build议为嵌套的PreferenceScreen创build顶级PreferenceActivity,然后通过意向调用这个新的活动:

 <PreferenceScreen android:key="key1" android:title="1 Item" android:summary=""> <intent android:action="android.intent.action.VIEW" android:targetPackage="com.example" android:targetClass="com.example.PreferenceActivity2"/> </PreferenceScreen> 

我不必将这个主题应用于除了应用程序之外的任何东西。

您也可以使用此技术来覆盖内部首选项屏幕的样式:

 @Override public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { super.onPreferenceTreeClick(preferenceScreen, preference); if (preference != null) { if (preference instanceof PreferenceScreen) { if (((PreferenceScreen) preference).getDialog() != null) { ((PreferenceScreen) preference) .getDialog() .getWindow() .getDecorView() .setBackgroundDrawable( this .getWindow() .getDecorView() .getBackground() .getConstantState() .newDrawable() ); } } } return false; } 

此代码将主要首选项屏幕的样式应用于点击的首选项屏幕。

最后,我发现如何以编程方式(通过Java代码)更改“PreferenceActivity”的主题

改变主题就是这样做的:

  @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); 方法在那里。

这似乎是一个错误。 请参阅http://code.google.com/p/android/issues/detail?id=4611

有一个更简单的解决scheme,如果你可以使用什么样的黑魔法来完成这个…

查看PreferenceScreen#showDialog(Bundle)的源代码,我们看到使用通过mContext.getThemeResId()获得的主题资源创build了对话框,然后在ContextThemeWrapper使用该主题资源。

这可以大大帮助我们,因为PreferenceScreen中使用的Context实际上是我们的PreferenceActivity ,所以我们所要做的就是覆盖getThemeResId()方法(这是从公共API隐藏的),提供我们的自定义主题, sub-PreferenceScreen现在使用我们想要的任何自定义主题资源!

 /** * This is a hack to provide our own theme for the PreferenceScreen's dialog. * * @see android.preference.PreferenceScreen#showDialog(Bundle) */ public int getThemeResId() { return R.style.Theme_MyApp_PreferenceScreen; } 

请注意,由于此方法使用@hide注释,因此无法使用通常在此情况下使用的@Override注释。 而且我们也不能调用super.getThemeResId()方法。 如果你确实希望能够有条件地覆盖这个,并通过超级实现作为后备,你将不得不使用Reflection来获得超级实现的方法:

  try { ((Object) this).getClass().getMethod("getThemeResId").invoke(this); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); }