Un arrière plan noir pour l'apparence de base des boutons :
Un arrière plan orange pour l'apparence des boutons lorsque ceux-ci sont pressés par l'utilisateur :
Un arrière plan rouge pour les boutons désactivés :
Ces trois arrières plans au format PNG doivent être placés dans le répertoire /res/drawables de notre application Android. L'étape suivante consiste à paramétrer l'arrière plan correspondant aux différents états de nos boutons personnalisés. Cette configuration se fait au moyen du fichier XML suivant :
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="false" android:drawable="@drawable/btn_red" /> <item android:state_pressed="true" android:state_enabled="true" android:drawable="@drawable/btn_orange" /> <item android:state_focused="true" android:state_enabled="true" android:drawable="@drawable/btn_orange" /> <item android:state_enabled="true" android:drawable="@drawable/btn_black" /> </selector>
Chaque état possible des boutons est associé à un arrière plan. Lorsque le bouton est rendu, l'arrière plan sélectionné est le premier pour lequel l'état déclaré dans le fichier XML concorde avec celui du bouton (L'API considère le premier concordant plutôt que celui qui vérifie le plus grand nombre de critères). Dans l'exemple ci-dessous, l'arrière plan orange ne sera jamais rendu pour un bouton pressé car le premier arrière plan déclaré dans le fichier XML est associé à un état toujours vérifié lorsque le bouton est actif et pressé :
<item android:state_enabled="false" android:drawable="@drawable/btn_red" /> <item android:state_pressed="true" android:state_enabled="false" android:drawable="@drawable/btn_orange" />
Pour que l'arrière plan orange soit rendu pour les boutons inactifs et pressés, il faut placer les conditions les plus restrictives en premier, avant celles paramétrant l'affichage de l'arrière plan rouge :
<item android:state_pressed="true" android:state_enabled="false" android:drawable="@drawable/btn_orange" /> <item android:state_enabled="false" android:drawable="@drawable/btn_red" />
Un fois notre selector enregistré dans le fichier btn_custom.xml du répertoire /res/drawables, il nous est possible de déclarer un style applicable aux boutons de notre application Android. Les styles sont déclarables dans les fichiers /res/values/styles.xml et /res/values/themes.xml. Le premier permet de paramétrer l'apparence complète du bouton (arrière plan, police, taille et couleur du text, ...) :
<resources> <style name="Button" parent="@android:style/Widget.Button"> <item name="android:gravity">center_vertical|center_horizontal</item> <item name="android:textColor">#FFFFFFFF</item> <item name="android:shadowColor">#FF000000</item> <item name="android:shadowDx">0</item> <item name="android:shadowDy">-1</item> <item name="android:shadowRadius">0.2</item> <item name="android:textSize">16dip</item> <item name="android:textStyle">bold</item> <item name="android:background">@drawable/btn_custom</item> <item name="android:focusable">true</item> <item name="android:clickable">true</item> </style> </resources>
Le second est utilisé pour appliquer le style à l'ensemble des Button d'un application déclarant le thème CustomButton :
<resources> <style name="CustomButton" parent="android:style/Theme.NoTitleBar"> <item name="android:buttonStyle">@style/Button</item> </style> </resources>
Pour appliquer ce thème à notre application, il faut utiliser l'attribut android:theme de la balise application <application> dans le fichier AndroidManifest.xml :
<application android:icon="@drawable/icon" android:label="Custom button" android:theme="@style/CustomButton">
Et voilà à quoi les boutons déclarés dans nos Layout vont ressembler :
Cette customisation peut s'appliquer de la même manière à l'ensemble des éléments de l'interface utilisateur : Menu, List, Checkbox, EditText, ... Cela permet de créer des applications avec une expérience utilisateur entièrement personnalisée.