Slide 1

Slide 1 text

De à

Slide 2

Slide 2 text

Le vectoriel, c'est très utile, mais ça a quelques pièges qu'il faut connaître Déjà, c'est quoi un SVG? -> Scalable Vector Graphics

Slide 3

Slide 3 text

SVG ? Dans la pratique, cette note de musique, c'est un fichier xml :

Slide 4

Slide 4 text

→ viewBox : taille de ma zone de dessin. Ici je dessine dans un carré de 24 de côté → path : liste d'instructions, qui tiennent dans la viewBox, si je dessine en 24 24 je suis en bas à droite de mon image. et 50 50 n'aurait aucun sens ici puisqu'en dehors de la viewbox

Slide 5

Slide 5 text

→ fill : couleur de remplissage → height / width : la taille de l'image que je veux générer, en pixels. peut être totalement différent de la viewBox

Slide 6

Slide 6 text

Path Liste d'instructions : M : move L : line V : vertical line A : arc (curve) C : cubic bezier curve

Slide 7

Slide 7 text

Path La spec svg définit beaucoup d'instructions. À chaque fois c'est une lettre suivie d'une série de coordonnées. c'est ça que contient un path comme celui-ci :

Slide 8

Slide 8 text

Path certaines instructions sont écrites en majuscules, d'autres en minuscules : lettre majuscule : coordonnées absolues lettre minuscule : coordonnées relatives : on part du point d'arrivée de l'insctruction précédente.

Slide 9

Slide 9 text

Il y a d'autres choses dans la spec, par exemple le linecap :

Slide 10

Slide 10 text

Très souvent lors de l'export Sketch rajoute un stroke-width, stroke-color, etc dans le svg pour chaque path. Une fois importé dans Android Studio vous pouvez généralement le virer, c'est un bug de leur exporteur.

Slide 11

Slide 11 text

Et ainsi de suite, la spec SVG, c'est 800 pages ! Nous on travaille sur Android. On n'a pas besoin de tout ça.

Slide 12

Slide 12 text

Si je prends un svg : et l'importe dans Android Studio (drawable/new vector drawable)

Slide 13

Slide 13 text

j'obtiens ceci :

Slide 14

Slide 14 text

j'ai les mêmes composants qu'un svg standard, sauf qu'ici c'est un drawable android. Quand j'inflate cette resource android, j'obtiens un VectorDrawable.

Slide 15

Slide 15 text

c'est un drawable android standard, je peux utiliser des @ :

Slide 16

Slide 16 text

Problème : le VectorDrawable ne supporte pas toute la spec SVG

Slide 17

Slide 17 text

problème le plus commun : -> even-odd Rêgle qui permet de coder des zones pleines et vides suivant qu'elles coupent un nombre de tracés pair ou impair

Slide 18

Slide 18 text

Sketch ne donne pas les mains aux designers là dessus. C'est un outil qui permet de faire du vectoriel, mais qui n'est pas pensé pour le format svg. Résultat: L'export de svg dans sketch peut vous générer des svgs non gérés par android, et les designers n'ont pas souvent la main dessus

Slide 19

Slide 19 text

exemple de svg avec la rêgle even-odd F5F3925F-A5DA-443C-94DA-B08D695ADAAF

Slide 20

Slide 20 text

solution : cette webapp permet de nettoyer la plupart des svgs pour retirer ces rêgles de fill problématiques. http://a-student.github.io/SvgToVectorDrawableConverter.Web/ Il faut juste faire attention de bien cocher Specify --fix-fill-type

Slide 21

Slide 21 text

et pour Android < 21 ? Déjà, il faut rajouter une ligne dans la config gradle defaultConfig { applicationId 'deezer.android.app' minSdkVersion minSdk targetSdkVersion targetSdk multiDexEnabled true vectorDrawables.useSupportLibrary = true }

Slide 22

Slide 22 text

vectorDrawables.useSupportLibrary = true dit à la support lib de ne pas générer de pngs pour nos vecteurs, on va se débrouiller pour afficher des VectorDrawables, même <21

Slide 23

Slide 23 text

Deuxième opération, dans BaseActivity : // setup the support lib so we can use vector Resources static { AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); } demande à la support lib de hacker l'inflation de drawables quand c'est possible, pour qu'elle prenne en charge les selectors contenant des svgs (on verra ensuite pourquoi c'est très utile)

Slide 24

Slide 24 text

Utilisation : Pour une imageView, j'ai juste à utiliser srcCompat, qui va appeler une méthode de AppCompatImageView qui gère les vectorDrawable, même en API 16

Slide 25

Slide 25 text

Problème : drawable:left -> appelé dans le constructeur de TextView, pas possible de créer une classe fille qui corrige le comportement du constructeur

Slide 26

Slide 26 text

C'est l'heure du hack crado !

Slide 27

Slide 27 text

c'est à ça que sert setCompatVectorFromResourcesEnabled Le hack de la support lib permet d'inflater des vectorDrawableCompat mais pas directement, uniquement s'ils sont wrappés dans un selector d'où ce selector qui ne contient qu'un seul élément. A utiliser à chaque fois qu'on a unCompoundDrawable` (TextView, CheckBox, ..)

Slide 28

Slide 28 text

Deuxième problème : context.getDrawable(id); ContextCompat.getDrawable(context, vectorId); Context et même ContextCompat ne gèrent pas les vectorDrawables Pour les vecteurs, utilisez plutôt : AppCompatDrawableManager.getDrawable(context, vectorId);

Slide 29

Slide 29 text

Presque sauvés ! sauf ... Glide.with(ctx) .load(url) .placeholder(R.drawable.placeholder) .into(view); dans Glide/GenericRequest : private Drawable getPlaceholderDrawable() { if (placeholderDrawable == null && placeholderResourceId > 0) { placeholderDrawable = context.getResources().getDrawable(placeholderResourceId); } return placeholderDrawable; }

Slide 30

Slide 30 text

Les placeholders/error/fallbacks de Glide n'utilisent pas la support lib ! On peut éventuellement passer directement un drawable créé via AppCompatDrawableManager à Glide

Slide 31

Slide 31 text

RemoteView Les remoteViews ne font pas non plus appel à la support lib

Slide 32

Slide 32 text

Comment faire ? Pour ces cas ci, il faut souvent passer par des drawables raster classiques pour les vieilles versions dans chaque bucket. Et le bucket anydpi-v21 permet de les overrider tous à partir de lollipop

Slide 33

Slide 33 text

Et les animations ?

Slide 34

Slide 34 text

Slide 35

Slide 35 text

Slide 36

Slide 36 text

Slide 37

Slide 37 text

valueFrom et valueTo doivent être compatibles : contenir les mêmes instructions dans le même ordre avec juste des coordonnées différentes. Pour les animations, la principale limitation c'est qu'il manque encore des outils graphiques pour modifier les paths de manière efficace.

Slide 38

Slide 38 text

Comme solution un peu plus efficace que d'écrire tous les paths à la main, il y a entre autres https://romannurik.github.io/AndroidIconAnimator/ mais toujours en cours de dev