2010-04-11 18 views
25

Hola a todos me han puesto el tema en el archivo de manifiesto de la siguiente manera:PreferenceActivity y el tema no aplicar

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

Pero tengo un problema en las preferencias de actividad, en las principales preferencias del tema muestra OK, pero si Llego a una preferencia secundaria, el tema se vuelve desordenado, no es blanco como debería, está todo oscuro y la fuente es negra, por lo que no se puede ver mucho, y cuando empiezo a hacer clic en cualquier elemento, a veces blanco como deberían pero volver a negro poco después. Esto solo ocurre en 2.1, tanto en el dispositivo real como en el emulador. Probado en el emulador ejecutando 1.6 y estaba funcionando correctamente. Aquí es parte del código del archivo XML preferencias:

<?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> 

Y aquí está una captura de pantalla:

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

soluciones provisionales?

+0

muy útil tal vez, pero utilizo el tema claro en la mayoría de mis aplicaciones, pero dejo las preferencias en el tema negro predeterminado porque parece apropiado, mi opinión es que los usuarios esperarán que todas las preferencias de las aplicaciones tengan el mismo estilo. –

+0

¡Gran idea! Gracias. Ahora, ¿cómo puedo marcar esta pregunta si la respuesta fue un comentario? –

Respuesta

15

Alguien acaba de publicar una solución en http://code.google.com/p/android/issues/detail?id=4611

En pocas palabras, los mejores pantallas de preferencias nivel parecen reconocer el tema pero no los anidados. Así que la solución recomienda crear PreferenceActivity nivel superior para PREFERENCE anidado y luego invocar esta nueva actividad a través de la intención:

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

que no tenía que aplicar el tema a otra cosa que la propia aplicación.

+5

Compruebe el enlace en la respuesta, ahora hay una solución más simple, vea el Comentario 35 – powder366

+0

Hay otra solución aún más fácil que estas dos soluciones; ver mi respuesta http://stackoverflow.com/a/25613182/231078. – Joe

+0

no realmente @Joe – Ewoks

3

Al fin encontré la manera de cambiar el tema de "PreferenceActivity" mediante programación (a través de código java)

Para cambiar el tema acaba de hacer como esto:

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

Siempre llame setTheme(R.style.yourtheme); método antes de super.onCreate(savedInstanceState); método. Al hacer esto, producirá el resultado como se muestra a continuación.

enter image description here

eso es todo.

Si llama al método setTheme(R.style.yourtheme); después del método super.onCreate(savedInstanceState);, producirá el resultado como se muestra a continuación.

enter image description here

Nota: Los temas no se reconocen por PREFERENCE anidado. Para aplicar el tema a esa PreferenceScreen anidada, debe crear otra PreferenceActivity para esa PreferenceScreen anidada y llamar allí al método setTheme(R.style.yourtheme);.

+0

Esto debería haber sido enviado más. – faraday

+0

¡Sí, estoy de acuerdo! ¡Puedo confirmar que funciona y es la solución más simple! –

4

También puede utilizar esta técnica para anular los estilos de las pantallas de preferencias internas:

Este código se aplica el estilo de la pantalla principal de preferencia a la pantalla de preferencias se ha hecho clic.

+0

¡Gracias! ... esta solución funcionó para mí. – user836026

+0

¡De nada! :) – webmaster

+0

¡Eso resolvió mi problema sin problemas como la seda! ¡GRACIAS! – aveschini

0

Hay una solución aún más fácil, si estás de acuerdo con el uso de lo que parece magia negra para lograr esto ...

Al observar el origen de PreferenceScreen#showDialog(Bundle), vemos que el diálogo se crea utilizando el recurso de tema obtenido a través de mContext.getThemeResId(), que luego se utiliza en un ContextThemeWrapper.

Esto nos puede ayudar considerablemente, debido a que el Context que se utilizan en el PreferenceScreen es en realidad nuestra PreferenceActivity, por lo que todo lo que tenemos que hacer es reemplazar el getThemeResId() método (que está oculto a la API pública), para proporcionar nuestro tema personalizado, ¡y la subpreferenceScreen ahora usa cualquier recurso de tema personalizado que quisiéramos!

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

Tenga en cuenta que debido a este método se anota con @hide, no podemos usar la anotación @Override que normalmente se utiliza en este caso; y tampoco podemos llamar al método super.getThemeResId(). Si realmente, realmente quiere ser capaz de anular condicionalmente esto y llamar a través de la implementación súper como punto de retorno, que tendrá que utilizar la reflexión para llegar al método de los súper de aplicación:

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

No funciona ... ¿puedes dar un ejemplo más completo? –

+0

La reflexión casi siempre es una solución sucia a largo plazo. – Ewoks

Cuestiones relacionadas