Introduction aux styles et aux thèmes
Date de publication : 27/01/2011.
Par
Cyril Mottier (AndroidDevBlog) (Blog)
Cet article vous présente une particularité assez plaisante d'Android
vis-à-vis des autres systèmes d'exploitation mobiles : la possibilité
de créer des interfaces graphiques à l'aide de simples fichiers
XML.
N'hésitez pas à nous faire part de votre avis sur cet article :
4 commentaires
Introduction
De toutes les particularités d'Android vis-à-vis des autres systèmes
d'exploitation mobiles, une me plait tout particulièrement : la
possibilité de créer des interfaces graphiques à l'aide de simples
fichiers XML. Cette particularité favorise grandement la clarté
du code source des applications. En effet, séparer la description
de l'interface graphique (layout XML) de la logique applicative
(code Java) est en gage d'extensibilité.
Etant très attaché aux technologies du Web (XHTML,
JavaScript, CSS, etc.),
j'ai souvent tendance à comparer la création d'applications
au développement d'un site Internet.
Ainsi :
-
les layouts s'apparentent au contenu XHTML ;
-
le code applicatif à la logique JavaScript.
Les aficionados du développement Web auront probablement
remarqué qu'une composante est absente du listing précédent : la
présentation, généralement décrite via une feuille de style
CSS. L'utilisation du CSS permet
ainsi de définir un ensemble de styles applicables aux différentes
balises de l'interface graphique. Android inclut
un système proche des CSS : les styles et les thèmes.
Souvent sous-utilisés, les styles et thèmes
Android
permettent de grandement factoriser les styles et donc de conserver
une cohérence à travers une application. C'est une des raisons pour lesquelles
GreenDroid
utilise largement ces possibilités. Nous allons donc en faire une
rapide présentation dans les lignes qui suivent.
 |
Note :
L'ensemble des démos de cet article sont disponibles dans cette
archive.
Cette dernière ne contient qu'un unique projet avec lequel il vous
faudra "jouer" pour appliquer telle ou telle méthode de style.
N'hésitez pas à laisser un commentaire si vous n'arrivez vraiment
pas à obtenir un résultat fonctionnel !
|
Appliquer un style à une balise
Prenons le code suivant :
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:text="Bonjour !!!" />
|
Ce code n'a rien de compliqué et est même plutôt "classique". Par
défaut Android oblige le développeur à définir une hauteur et une
largeur pour chacune des vues. C'est ce qui nous oblige à souvent
ajouter du code du style android:layout_[width|height]="[wrap_content|fill_parent]".
Il faut avouer que ça peut devenir assez rébarbatif. Il est néanmoins
possible de réduire le code de la façon suivante :
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/FillParent"
android:gravity="center"
android:text="Bonjour !!!" />
|
 |
Note : L'attribut XML style n'appartenant
pas au namespace android, il n'est pas nécessaire de le préfixer
par android:.
|
Pour ce faire, il suffit de créer un style FillParent
dans les styles du projet :
<style name="FillParent">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">fill_parent</item>
</style>
|
 |
Note : On utilise généralement le fichier res/values/styles.xml
pour définir l'ensemble des styles d'un projet. Sachez néanmoins
que cela n'a rien d'obligatoire. La seule nécessité est de définir
le style dans la balise <resources /> dans
un fichier présent dans res/values.
|
Notion d'héritage
Contrairement aux feuilles de style CSS, les styles Android ne
fonctionnent pas en cascade. Ainsi une balise <TextView>
contenue dans un <LinearLayout> disposant
d'un style @style/MyStyle n'hérite aucunement des
propriétés de son parent. Il est néanmoins possible de faire hériter
un style d'un autre style. Si nous souhaitons maintenant créer un
style forçant la vue à prendre la taille de son parent et à centrer
son contenu nous pouvons définir :
<style name="FillParent.Centered" parent="@style/FillParent">
<item name="android:gravity">center</item>
</style>
|
Il est également possible de simplifier cette déclaration de la
façon suivante :
<style name="FillParent.Centered">
<item name="android:gravity">center</item>
</style>
|
Lorsque le nom d'un style est du format <Part1>.<Part2>,
Android considère automatiquement que le parent est le style de nom
@style/Part1.
En utilisant ce nouveau style, il est possible de simplifier notre
layout exemple :
<TextView
style="@style/FillParent.Centered"
android:text="Bonjour !!!" />
|
Les thèmes
Les thèmes Android ne sont rien d'autre que des styles s'appliquant
à l'ensemble des balises de vos layouts. Pour contrer le problème
de android:layout_[width|height] obligatoires,
on peut donc, par exemple, imaginer un thème initialisant l'ensemble
de ces valeurs à fill_parent. On commence donc
par créer un style nommé Theme.Custom héritant
du thème Android Theme.Black. Traditionnellement,
bien qu'un style soit un thème, on le place dans un fichier nommé
res/values/themes.xml.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.Custom" parent="@android:style/Theme.Black">
<item name="android:layout_height">fill_parent</item>
<item name="android:layout_width">fill_parent</item>
</style>
</resources>
|
On applique ensuite ce thème à l'ensemble de l'application en ajoutant
l'attribut XML android:theme="@style/Theme.Custom"
à la balise <application /> de notre
AndroidManifest.xml. Le code du layout est donc
de la forme suivante :
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="center"
android:text="Bonjour !" />
|
Les attributs de style
Utilisés tels quels, les thèmes n'ont que peu d'intérêt. En effet,
appliquer une valeur par défaut à l'ensemble des balises de votre
application est quelque peu hasardeux et inutile. Les thèmes prennent
tout leur sens lorsqu'ils sont utilisés en conjonction avec les
attributs de style.
Un attribut de style peut-être utilisé comme "indirection de style".
Plutôt que de longs discours, appliquons un attribut de style à
notre <TextView />. On commence par créer
un nouvel attribut nommé myTextViewAttr dans le
fichier res/values/attrs.xml :
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="myTextViewAttr" />
</resources>
|
Il ne nous reste plus maintenant qu'à appliquer ce style au layout
voulu :
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
style="?attr/myTextViewAttr"
android:text="Bonjour !" />
|
La <TextView /> précédente dispose de l'attribut
de style ?attr/myTextViewAttr. On notera bien
la présence d'un caractère "?" en lieu et place du traditionnel "@".
L'utilisation du point d'interrogation permet d'informer le système
que la ressource de style recherchée n'est pas myTextViewAttr
(nous aurions alors écrit @style/myTextViewAttr)
mais un style "pointé" par l'attribut myTextViewAttr.
Si on lance notre application dans l'état, nous obtenons une erreur
affirmant qu'aucun des attributs android:layout_[height|width]
n'a été initialisé. Ce résultat est tout à fait logique car le
style qui se cache derrière l'attribut myTextViewAttr
n'a pas été défini. Pour le définir, il suffit de l'initialiser
dans le thème de notre application !
<style name="Theme.Custom_2" parent="@android:style/Theme.Black">
<item name="myTextViewAttr">@style/FillParent.Centered</item>
</style>
|
L'application est maintenant parfaitement fonctionnelle et applique
le style @style/FillParent.Centered à l'ensemble
des balises disposant de l'attribut de style ?attr/myTextViewAttr.
Simple et puissant n'est-ce pas ?
Etendre des thèmes Android
L'ensemble des fonctionnalités décrites dans cet article sont accessibles
au développeur aussi bien pour créer ses propres styles que pour
étendre et modifier les thèmes existants d'Android. Ainsi, lorsque
vous souhaitez développer une application à dominante "noir sur blanc",
il suffit de créer un thème héritant de @android:style/Theme.Light
et de modifier les attributs à votre convenance. Voici un exemple
de thème Android supprimant la fameuse ombre en haut de l'écran
et modifiant le style par défaut de la titlebar :
<style name="Theme.Custom_3" parent="@style/Theme.Custom_2">
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowTitleStyle">@style/WindowTitle</item>
<item name="android:windowTitleBackgroundStyle">@style/WindowTitleBackground</item>
</style>
|
Les styles associés sont définis de la façon suivante :
<style name="WindowTitleBackground">
<item name="android:background">@drawable/title_bar</item>
</style>
<style name="WindowTitle" parent="@android:style/WindowTitle">
<item name="android:textAppearance">@style/TextAppearance.WindowTitle</item>
</style>
<style name="TextAppearance.WindowTitle" parent="@android:style/TextAppearance.WindowTitle">
<item name="android:textStyle">bold|italic</item>
</style>
|
Le résultat est quelque peu coloré !
A mon grand regret, la documentation sur les différents attributs
de style d'Android est assez pauvre. Jetez donc un oeil à la
documentation de
R.attr
et n'hésitez surtout pas à regarder le code source de la plateforme
pour connaître l'utilité de tel ou tel attribut. Stylez/Thèmez bien !
Remerciements


Les sources présentées sur cette page sont libres de droits
et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation
constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ©
25/01/2011 Cyril Mottier. Aucune reproduction,
même partielle, ne peut être faite de ce site et de l'ensemble de son contenu :
textes, documents, images, etc. sans l'autorisation expresse de l'auteur.
Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 €
de dommages et intérêts.
Cette page est déposée.