Définition de styles globaux pour les vues dans Android

125

Disons que je veux que toutes les TextViewinstances de mon application aient textColor="#ffffff". Existe-t-il un moyen de définir cela dans un seul endroit au lieu de le définir pour chacun TextView?

Emanuil Rusev
la source
1
J'ai mis à jour ma question pour qu'elle soit plus complète.
Cristian
Je fais quelque chose de similaire ICI !!! stackoverflow.com/questions/17103894/…
toobsco42

Réponses:

250

En fait, vous pouvez définir un style par défaut pour TextViews (et la plupart des autres widgets intégrés) sans avoir besoin de créer une classe Java personnalisée ou de définir le style individuellement.

Si vous regardez dans themes.xmlla source Android, vous verrez un tas d'attributs pour le style par défaut pour divers widgets. La clé est l' attribut textViewStyle(ou editTextStyle, etc.) que vous remplacez dans votre thème personnalisé. Vous pouvez les remplacer de la manière suivante:

Créez un styles.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyTheme" parent="android:Theme">
    <item name="android:textViewStyle">@style/MyTextViewStyle</item>
</style>

<style name="MyTextViewStyle" parent="android:Widget.TextView">
    <item name="android:textColor">#F00</item>
    <item name="android:textStyle">bold</item>
</style>
</resources>

Ensuite, appliquez simplement ce thème à votre application dans AndroidManifest.xml:

<application […] android:theme="@style/MyTheme">

Et toutes vos vues de texte utiliseront par défaut le style défini dans MyTextViewStyle(dans cet exemple, gras et rouge)!

Cela a été testé sur des appareils à partir du niveau d'API 4 et semble fonctionner très bien.

Steve Pomeroy
la source
1
La solution la plus élégante que j'ai vue jusqu'à présent.
Italo Borssatto
@Steve, si j'inclus l'élément <item name="android:textViewStyle">@style/MyTextViewStyle</item>dans le style MyTheme et que j'applique ensuite le style à mon application, tous mes TextViews seront affichés en fonction du style (même le nom de l'application dans la barre d'action). Comment résoudre le problème avec la barre d'action? Je veux qu'il ait l'apparence par défaut. Github
Maksim Dmitriev
@Steve, Comment appliquer les deux thèmes (barre d'action et widget) sur l'application
Pratik Butani
Je ne sais pas comment différencier l'ActionBar des autres choses. Vous pourrez peut-être trouver où votre style ActionBar est défini, puis <item name="android:textViewStyle">@style/MyTextViewStyle</item>y mettre aussi, en indiquant simplement la valeur par défaut d'ActionBar (ou quelque chose de similaire)
Steve Pomeroy
@StevePomeroy cela ne fonctionne pas pour moi .. pouvez-vous fournir une assistance. Mon style pour les TextViews reste le même. Y a-t-il un minimum d'éléments que je dois définir ou y a-t-il des éléments que je ne suis pas autorisé à définir?
Mike
52

Il existe deux façons de procéder:

1. Utilisation des styles

Vous pouvez définir vos propres styles en créant des fichiers XML dans le res/valuesrépertoire. Supposons donc que vous souhaitiez avoir du texte en rouge et en gras, puis vous créez un fichier avec ce contenu:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="MyRedTheme" parent="android:Theme.Light">
    <item name="android:textAppearance">@style/MyRedTextAppearance</item>
  </style>
  <style name="MyRedTextAppearance" parent="@android:style/TextAppearance">
    <item name="android:textColor">#F00</item>
    <item name="android:textStyle">bold</item>
  </style>
</resources>

Vous pouvez le nommer comme vous le souhaitez, par exemple res/values/red.xml. Ensuite, la seule chose que vous avez à faire est d'utiliser cette vue dans les widgets que vous souhaitez, par exemple:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView
    style="@style/MyRedTheme"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="This is red, isn't it?"
    />
</LinearLayout>

Pour plus d'informations, vous pouvez lire cet article: Comprendre les thèmes et styles Android

2. Utilisation de classes personnalisées

C'est une autre façon possible d'y parvenir, et ce serait de fournir le vôtre TextViewqui définira toujours la couleur du texte à ce que vous voulez; par exemple:

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.widget.TextView;
public class RedTextView extends TextView{
    public RedTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setTextColor(Color.RED);
    }
}

Ensuite, il vous suffit de le traiter comme normal TextViewdans votre fichier XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<org.example.RedTextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="This is red, isn't it?"
    />
</LinearLayout>

Que vous utilisiez l'un ou l'autre choix dépend de vos besoins. Si la seule chose que vous souhaitez faire est de modifier l'apparence, la meilleure approche est la première. D'autre part, si vous souhaitez modifier l'apparence et ajouter de nouvelles fonctionnalités à vos widgets, la seconde est la voie à suivre.

Cristian
la source
l'utilisation de classes personnalisées doit être préférée car c'est une approche plus propre et permet de conserver un fichier XML léger.
Amit Kumar
@AmitKumar Non, ils ne devraient pas! Dans ce cas particulier, cela signifierait utiliser une classe personnalisée distincte pour chaque valeur d'attribut différente. Cela produit beaucoup de code de ballonnement et rend la mise en page réelle non lisible (vous devrez visiter chaque classe pour voir ce qu'elle fait au lieu de simplement lire quelques lignes xml). Les classes personnalisées ne doivent être utilisées que si vous modifiez le comportement, mais pas si le seul changement est l'aspect de la vue.
Andre
N'est-il pas possible de définir le style d'une vue personnalisée à partir de XML? Pourquoi ne pouvons-nous pas l'utiliser dans le custom_view_layout.xmlfichier utilisé pour gonfler une classe personnalisée?
lucidbrot le
5

Pour la couleur du texte par défaut TextView, définissez android:textColorTertiarydans votre thème la couleur souhaitée:

<item name="android:textColorTertiary">@color/your_text_color</item>

De nombreuses autres couleurs de contrôle Android peuvent être contrôlées à l'aide d'attributs de structure ou de prise en charge des attributs de bibliothèque si vous utilisez la bibliothèque de prise en charge.

Pour obtenir une liste des attributs que vous pouvez définir, consultez le code source Android de styles.xmlet themes.xml, ou cet essentiel très utile de Dan Lew, essayez de changer chaque valeur et voyez ce qu'elles changent à l'écran.

hidro
la source
Merci mec! J'ai passé beaucoup de temps à comprendre pourquoi textColorPrimary ne fonctionne pas.
pratt
3

Définissez un style et utilisez-le sur chaque widget, définissez un thème qui remplace la valeur par défaut d'Android pour ce widget ou définissez une ressource de chaîne et référencez-la dans chaque widget

TWH
la source