Как изменить тему PreferenceActivity?

Я пытаюсь изменить тему для PreferenceActivity в моем приложении, и я просто не могу заставить ее работать.

Это xml:

    <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

        <SwitchPreference android:title="Auto Clear" android:key="autoclear" android:summary="Clear the command line when the code is being executed." android:defaultValue="false"/>
        <ListPreference android:title="Choose a theme" android:negativeButtonText="" android:dialogTitle="" android:key="theme" android:entries="@array/themesList" android:entryValues="@array/themesList" android:defaultValue="Default" />

</PreferenceScreen>

И это PreferenceActivity:

    @Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);

    this.setTheme(R.style.AppTheme);

    addPreferencesFromResource(R.xml.preferences);

}

И результат:

Result

Ответ 1

Вы пытались применить тему к тегу активности в манифесте? Вот как я это делал раньше -

<activity 
  android:label="@string/app_name" 
  android:name="com.example.MyPreferenceActivity"
  android:theme="@android:style/Theme.Black"
  android:exported="true"
  android:icon="@drawable/ic_launcher"></activity>

EDIT:

Другой вариант, который вы могли бы попробовать, - переопределить onApplyThemeResource(Resources.Theme theme, int resid, boolean first). Глядя на исходный код Android, setTheme будет внутренне вызывать метод.

/**
 * Called by {@link #setTheme} and {@link #getTheme} to apply a theme
 * resource to the current Theme object.  Can override to change the
 * default (simple) behavior.  This method will not be called in multiple
 * threads simultaneously.
 *
 * @param theme The Theme object being modified.
 * @param resid The theme style resource being applied to <var>theme</var>.
 * @param first Set to true if this is the first time a style is being
 *              applied to <var>theme</var>.
 */
protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) {
    theme.applyStyle(resid, true);
}

Ответ 2

Наконец-то я узнал, как программно изменить тему "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);.

Ответ 3

Если вы хотите изменить фон, вы можете использовать

public class FractalPreferenceActivity extends PreferenceActivity  {
   .......

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().setBackgroundDrawableResource(R.drawable.gradient); 
    getListView().setBackgroundColor(Color.TRANSPARENT); 
    getListView().setCacheColorHint(Color.TRANSPARENT); 

           .......
    }

}

Ответ 4

Я лично использую этот подход: для API ниже 11 я использую (каталог значений, файл themes.xml):

  <?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="MyTheme" parent="@android:style/Theme.Light.NoTitleBar"></style>

</resources>

для более высоких (например, каталог значений-v14, файл themes.xml):

    <?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="MyTheme" parent="@android:style/Theme.Holo.Light.NoActionBar"></style>

</resources>

и манифест:

 <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

Android автоматически выберет тему на основе API-интерфейса устройства и не будет необходимости указывать какие-либо темы в действиях (манифесте) или грамматически в коде...

themes

Ответ 5

Это звучит глупо, но использование setTheme() будет работать на всех ваших фрагментах, но не на основной активности предпочтений. Установите это в файле манифеста, и он внезапно начнет работать.

Я настраиваю тему динамически на основе пользовательских настроек, вызывая setTheme() перед onCreate из объекта диспетчера тем (он также уменьшает различные цвета и drawables, которые могут быть изменены темой, которую я не хочу устанавливать в стилях... главным образом потому, что слишком сложно понять, что это такое).

Не знаю, почему установка в манифесте делает работу setTheme(). Просто какой-то глюк, характерный для активности предпочтений, я думаю.