Comment importer un SVG dans un projet Android

 

Vous aussi, vous trouvez cela fastidieux de devoir pondre autant de versions d'un picto qu'il y a de résolutions (hdpi, xhdpi, xxhdpi…) pour votre appli Android ? Sans compter que ça alourdit le poids final de votre appli…

Une solution peut être l'utilisation d'une FontIcon. Une autre, permise depuis peu par Android Studio, consiste à importer une image vectorielle au format SVG et la convertir en un drawable au format XML (rien de surhumain à première vue, puisque le SVG est déjà un fichier texte avec des balises).

Ça se passe du côté d'un outil nommé Vector Asset Studio.

Accéder au Vector Asset Studio

En vue Android, clic-droit sur votre répertoire app > res > drawable. Choisir New > Vector asset.

Vector asset studio

Importez votre fichier SVG

Un assistant apparaît. Dans Asset Type, cochez  « Local file (SVG, PSD) »

Cliquez sur l'icône grise en forme de dossier à droite du champ Path. Cherchez et chargez votre fichier SVG (que vous avez au préalable créé sous Inkscape ou récupéré à partir d'une banque de fichiers vectoriels)

Chargement du fichier SVG

Par défaut, l'assistant va le renommer en le préfixant avec ic_

Android studio - Outil Vector Asset Studio

Cliquez Next. Confirmez le dossier dans lequel le drawable va être créé.

Choix du dossier

Et le voilà converti ! On retrouve notre nouveau vector drawable dans le répertoire /drawable.

Ça ne fonctionne pas ?

La plupart des avertissements peuvent être ignorés. Si vous avez des erreurs bloquantes, retournez sous Inkscape et simplifiez votre image. Par exemple, si vous avez utilisé du texte, pensez à le convertir en chemin avant d'essayer de l'importer sous Android studio, sinon vous aurez ces erreurs « <text> is not supported » et « <tspan> is not supported »

Erreur d'importation car élément texte non converti en chemin

Contenu du fichier final (pour les curieux)

Le contenu du fichier final ressemble à ça

<vector android:height="24dp" android:viewportHeight="77.74388"
android:viewportWidth="78.11705" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillAlpha="1" android:fillColor="#000000"
android:pathData="m61.8225,71.3451l-22.632,-22.632l-22.632,22.632l-9.9731,-9.9731l22.632,-22.632l-22.632,-22.632l9.7093,-9.7093l22.632,22.632l22.632,-22.632l9.9731,9.9731l-22.632,22.632l22.632,22.632z"
android:strokeColor="#00000000" android:strokeWidth="0.26458332"/>
</vector>

A comparer avec le contenu du SVG d'origine (j'ai un peu simplifié)

<svg>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-67.609043,-87.049766)">
<g
aria-label="+"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
id="text817"
transform="matrix(8.5103745,8.5103745,-8.5103745,8.5103745,271.9834,-1245.3873)">
<path
d="m 74.099576,90.849946 h -2.659339 v 2.659339 h -1.171881 v -2.659339 h -2.65934 v -1.140875 h 2.65934 v -2.65934 h 1.171881 v 2.65934 h 2.659339 z"
style="stroke-width:0.26458332"
id="path819"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccccc" />
</g>
</g>
</svg>

Il existe également un site web qui fait le job : SVG to Vector drawable

La flemme de créer vos propres SVG ?

Choisissez « Clip Art » dans Asset Type et cherchez votre bonheur parmi la collection de pictos material design proposée par Android Studio…

Rétrocompatibilité

Attention par contre : si vous visez la compatibilité avec d'anciennes versions d'Android (inférieures à Lollipop 5.0) – ce qui est très louable de votre part – pensez à ajouter vectorDrawables.useSupportLibrary = true dans le defaultConfig {} du build.gradle de l'app.

android {
  compileSdkVersion 29
    defaultConfig {
      applicationId "com.kdjwebdesign.monapp"
      minSdkVersion 15
      targetSdkVersion 29
      versionCode 1
      versionName "1.0"
      testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
      vectorDrawables.useSupportLibrary = true

   }
 ...
}

Et quand vous importez votre image dans votre layout, utilisez app:srcCompat au lieu de android:src

Sinon l'appli va crasher avec l'erreur « android.view.InflateException: Binary XML file line (…) Error inflating class ImageView » et « android.content.res.Resources$NotFoundException: File res/drawable/ic_couverts.xml from drawable »

<ImageView
android:id="@+id/recap_adapter_layout_iv_supprimer"
android:layout_width="64dp"
android:layout_height="64dp"
android:background="@drawable/circle"
app:srcCompat="@drawable/ic_supprimer"
android:tint="@color/white"
android:padding="16dp"
android:layout_alignParentRight="true"
/>

En vérifiant que vous avez bien ajouté la propriété xmlns:app= »http://schemas.android.com/apk/res-auto » à votre élément racine, sinon Android studio va râler « Namespace ‘app' not bound »…

Si vous appelez l'image en programmatique (c'est à dire dans votre code java), il vous faudra également ajouter un petit quelques chose… Un appel à setCompatVectorFromResourcesEnabled()

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); 
icone.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_supprimer));

En revanche, si vous voulez utiliser votre drawable xml en fond en l'appelant en tant que drawableLeft, drawableTop etc, pas de réelle solution : il faudra avoir recours à un bon vieux fichier png !

 

Source : Add multi-density vector graphics (doc officielle)

Karine SANCHE

Partager cet article