PreferenceActivity и тема не применяется

Привет всем Я установил тему в файле манифеста следующим образом:

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

Но у меня есть проблема в настройке Preferences, в основных настройках тема показывает хорошо, но если я получу суб-предпочтение, тема становится беспорядочной, она не белая, как должно, все темно, а шрифт Черный, поэтому вы не можете много увидеть, и когда я нажимаю на какие-либо предметы, они получат иногда белые, как они должны, но вскоре возвращаются к черному. Это происходит только в 2.1, как в реальном устройстве, так и в эмуляторе. Протестировано на эмуляторе под управлением 1.6, и он работал правильно. Вот часть кода 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> в <?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> 

И вот скриншот:

Alt text http://i39.tinypic.com/16hnhh3.png

Любые обходные пути?

Solutions Collecting From Web of "PreferenceActivity и тема не применяется"

Кто-то просто разместил обходной путь по адресу http://code.google.com/p/android/issues/detail?id=4611.

Вкратце, экраны предпочтений верхнего уровня, похоже, распознают тему, но вложенные ее нет. Таким образом, обходное решение рекомендует создать PreferenceActivity верхнего уровня для вложенного PreferenceScreen, а затем активировать эту новую активность с помощью намерения:

 <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; } 

Этот код применяет стиль экрана основных предпочтений к экрану предпочтений нажатых.

Наконец, я узнал, как программно изменить тему «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, вы должны сделать другую PreferenceActivity для этого вложенного PreferenceScreen и вызвать setTheme(R.style.yourtheme); Метод есть.

Кажется, это ошибка. См. http://code.google.com/p/android/issues/detail?id=4611.

Есть еще более простое решение, если вы в порядке используете то, что кажется черной магией, чтобы выполнить это …

Посмотрев на источник PreferenceScreen#showDialog(Bundle) , мы видим, что диалог создается с использованием ресурса темы, полученного с помощью mContext.getThemeResId() , который затем используется в ContextThemeWrapper .

Это может существенно помочь нам, потому что Context , используемый в PreferenceScreen на самом деле является нашей 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(); }