2010-04-11 18 views
25

Salut à tous j'ai mis le thème dans le fichier manifeste comme ceci:PreferenceActivity et le thème ne pas appliquer

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

Mais j'ai un problème dans l'activité Préférences, dans les principales préférences du thème montre ok, mais si J'arrive à une sous-préférence, le thème est en désordre, il n'est pas blanc comme il se doit, tout est sombre, et la police est noire donc on ne voit pas grand-chose, et quand je commence à cliquer sur blanc comme ils devraient, mais revenir au noir peu de temps après. Cela ne se produit que sur 2.1, à la fois sur le périphérique réel et l'émulateur. Testé sur l'émulateur en cours d'exécution 1.6 et il fonctionnait correctement. Voici une partie du code du fichier xml préférences:

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

Et voici une capture d'écran:

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

solutions de contournement?

+0

Pas très utile peut-être mais j'utilise le thème de la lumière dans la plupart de mes applications mais je laisse les préférences dans le thème noir par défaut car il semble approprié, mon avis est que les utilisateurs s'attendent à ce que toutes les préférences des applications aient le même style. –

+0

Bonne idée! Merci. Maintenant, comment puis-je marquer cette question répondu si la réponse était un commentaire? –

Répondre

15

Quelqu'un vient de poster une solution à http://code.google.com/p/android/issues/detail?id=4611

En bref, les meilleurs écrans de préférence de niveau semblent reconnaître le thème, mais ceux imbriqués non. Donc, la solution de contournement recommande de créer plus haut niveau PreferenceActivity pour PREFERENCE imbriqué puis en appelant cette nouvelle activité via l'intention:

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

Je ne devais pas appliquer le thème à quoi que ce soit, mais l'application elle-même.

+5

Vérifiez le lien dans la réponse, il y a une solution plus simple maintenant, voir le commentaire 35 – powder366

+0

Il existe une autre solution encore plus facile que ces deux solutions de contournement; voir ma réponse http://stackoverflow.com/a/25613182/231078. – Joe

+0

pas vraiment @Joe – Ewoks

3

Enfin je l'ai trouvé comment changer le thème de "PreferenceActivity" programme (via le code java)

Pour changer le thème le faire comme ceci:

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

Il faut toujours appeler setTheme(R.style.yourtheme); méthode avant super.onCreate(savedInstanceState); méthode. En faisant cela, cela produira un résultat comme indiqué ci-dessous.

enter image description here

C'est tout.

Si vous appelez la méthode setTheme(R.style.yourtheme); après la méthode super.onCreate(savedInstanceState);, le résultat sera comme indiqué ci-dessous.

enter image description here

Note: Les thèmes ne sont pas reconnaître par PREFERENCE imbriquées. Pour appliquer un thème à ce PreferenceScreen imbriqué, vous devez créer une autre PreferenceActivity pour ce PreferenceScreen imbriqué et y appeler la méthode setTheme(R.style.yourtheme);.

+0

Cela aurait dû être plus en vogue. – faraday

+0

Oui, je suis d'accord! Je peux confirmer que cela fonctionne et c'est la solution la plus simple! –

4

Vous pouvez également utiliser cette technique pour remplacer les styles des écrans de préférence internes:

Ce code applique le style de l'écran principal de préférence à l'écran de préférence cliquée.

+0

Merci !!! ... cette solution a fonctionné pour moi. – user836026

+0

Vous êtes les bienvenus! :) – webmaster

+0

Cela a résolu mon problème lisse comme de la soie! JE VOUS REMERCIE! – aveschini

0

Il existe une solution encore plus simple, si vous utilisez ce qui semble être de la magie noire pour accomplir cela ...

En regardant la source de PreferenceScreen#showDialog(Bundle), nous voyons que le dialogue est créé en utilisant la ressource de thème obtenue via mContext.getThemeResId(), qui est ensuite utilisé dans un ContextThemeWrapper.

Cela peut nous aider considérablement, parce que le Context utilisé dans le PreferenceScreen est en fait notre PreferenceActivity, donc tout ce que nous devons faire est de passer outre la méthode getThemeResId() (qui est caché à l'API publique), pour fournir notre thème personnalisé, et le sous-PreferenceScreen utilise maintenant n'importe quelle ressource de thème personnalisé que nous voulions!

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

Notez que parce que cette méthode est annotées avec @hide, nous ne pouvons pas utiliser l'annotation @Override qui serait normalement utilisé dans ce cas; et nous ne pouvons pas non plus appeler la méthode super.getThemeResId(). Si vous avez vraiment, vraiment voulez être en mesure de passer outre conditionnellement cela et appeler par la super mise en œuvre comme solution de repli, vous devrez utiliser la réflexion pour arriver à la méthode de la super mise en œuvre:

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

Ne fonctionne pas ... pouvez-vous fournir un exemple plus complet? –

+0

La réflexion est presque toujours une solution sale à long terme. – Ewoks