Подтвердить что ты не робот

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

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

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

Но у меня есть проблема в Activity 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>

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

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

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

4b9b3361

Ответ 1

Кто-нибудь просто разместил обходное решение в 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>

Мне не пришлось применять тему ни к чему, кроме самого приложения.

Ответ 2

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

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

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

Ответ 3

Наконец-то я узнал, как программно изменить тему "PreferenceActivity" (через Java-код)

Чтобы изменить тему, выполните следующие действия:

        @Override
        public void onCreate(Bundle savedInstanceState) {
        setTheme(R.style.Holo_Theme_Light);
        super.onCreate(savedInstanceState);
        }

Всегда вызывать метод setTheme(R.style.yourtheme); до метода super.onCreate(savedInstanceState);. Делая это, он будет давать результат, как показано ниже.

enter image description here

Что все.

Если вы вызовите метод setTheme(R.style.yourtheme); после метода super.onCreate(savedInstanceState);, он произведет результат, как показано ниже.

enter image description here

Примечание. Темы не распознаются вложенным PreferenceScreen. Чтобы применить тему к этому вложенному PreferenceScreen, вы должны сделать другую PreferenceActivity для этого вложенного PreferenceScreen и вызвать метод setTheme(R.style.yourtheme);.

Ответ 5

Там еще проще, если вы можете использовать то, что кажется черной магией, чтобы выполнить это...

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

Это может существенно помочь нам, потому что Context, используемый в PreferenceScreen, на самом деле является нашим PreferenceActivity, поэтому все, что нам нужно сделать, это переопределить метод getThemeResId() (который скрыт от общедоступного API), чтобы предоставить нашу настраиваемую тему, а суб-PreferenceScreen теперь использует любой настраиваемый ресурс темы, который мы хотели!

/**
 * This is a hack to provide our own theme for the PreferenceScreen 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();
        }