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.
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)
Par défaut, l'assistant va le renommer en le préfixant avec ic_
Cliquez Next. Confirmez le dossier dans lequel le drawable va être créé.
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 »
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)