Lors du développement d'applications Android, l'utilisaiton de ressources vectorielles (SVG convertis en XML) peut provoquer des plantages sur les appareils équipés d'une version d'Android inférieure à 5.0 (API 21). L'erreur classique rencontrée est la suivante : org.xmlpull.v1.XmlPullParserException: Binary XML file line #1: invalid drawable tag vector.
1. Configuration du projet et de l'environnement
La première étape consiste à configurer correctement Gradle pour permettre le support rétroactif des vecteurs via la bibliothèque de suport.
Dans le fichier build.gradle de votre module, ajoutez les dépendances nécessaires :
dependencies {
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:support-vector-drawable:28.0.0'
}
Ensuite, activez explicitement le support des vecteurs dans la section defaultConfig :
android {
defaultConfig {
// Pour Gradle 2.0 et supérieur
vectorDrawables.useSupportLibrary = true
}
}
Si vous utilisez une version très ancienne de Gradle (entre 1.5 et 2.0), la configuration diffère légèrement :
android {
defaultConfig {
generatedDensities = []
}
aaptOptions {
additionalParameters "--no-version-vectors"
}
}
2. Activation du support au niveau de l'Activity
Pour s'assurer que les ressources vectorielles sont correctement chargées via les ressources système, il est indispensable d'activer un commutateur spécifique dans votre classe Activity (qui doit hériter de AppCompatActivity). La méthode la plus robuste consiste à utiliser un bloc statique :
public class BaseActivity extends AppCompatActivity {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
}
}
3. Utilisation correcte dans les fichiers de mise en page (Layouts)
L'attribut standard android:src ne fonctionne pas de manière fiable avec les vecteurs sur les anciennes versions d'Android. Vous devez utiliser l'attribut défini dans l'espace de noms de l'application :
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_mon_vecteur" />
Notez que si votre Activity n'hérite pas directement de AppCompatActivity, vous devrez utiliser explicitement le composant AppCompatImageView dans votre fichier XML.
4. Conteneurs pour les composants secondaires (Buttons, TextViews)
Sur Android 5.0 et versions antérieures, l'utilisation directe d'un vecteur dans un Button ou comme compoundDrawable dans un TextView peut échouer. La solution consiste à encapsuler le vecteur dans un conteneur comme un selector ou une layer-list.
Exemple d'un fichier res/drawable/ic_wrapper.xml :
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/mon_vecteur_original" />
</selector>
Vous pouvez ensuite appliquer ce wrapper à n'importe quel composant :
<Button
android:id="@+id/btn_action"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Valider"
android:drawableLeft="@drawable/ic_wrapper" />
5. Cas particulier des TextViews
Le composant AppCompatTextView ne supporte pas nativement l'inflation des vecteurs via les attributs android:drawableStart ou android:drawableTop sur les anciennes API. Si l'astuce du selector ne suffit pas, il est recommandé de définir les icônes programmatiquement ou d'utiliser une implémentation personnalisée de TextView qui surcharge la gestion des drawables pour intercepter et charger correctement les ressources vectorielles.