Vector Assets – Android Conference Talks


hello and welcome to vector assets we're going to talk to you about making razor sharp images my name is Nick butcher I'm an engineer on the Google developer relations team these slides are available at this URL if you want to follow along or copy/paste any code later on so my goal today with this talk is that everyone should be using vector assets in their Android applications the reason why I think this is important is because Android devices come in many shapes and sizes and most importantly in different screen sizes and densities until recently most assets in Android applications have been a bitmap format things like PNG s now these have an intrinsic size and they kind of encode their data at the pixel level so they're specific to a certain density that's why in our Android applications we have to provide different versions of the same asset for different screen densities so you essentially have different copies of the same asset at different sizes contrast this to a vector format which describes the image inside this file so you only need to provide it once now this has a few benefits overall I'd summarize them that vector assets are sharp they're small and they're animatable they're sharp because they can be resized to any screen size really raster assets can deteriorate if you scale them particularly if you scale them up where you'll see some artifacts like on this circle here because vector assets are defined over kind of a virtual screen size they'll be show up at any density vector assets are textual so they kind of compress very very well and also you only need to provide one single version rather than multiple versions per screen density so as such they tend to be much smaller allowing you to create smaller spelter apks and lastly because vector assets describe the image actually opens up opportunities for doing new things like animating the individual parts of the image or reclaiming rooms dynamically at runtime so there's new things you can do with X's so if you think vectors sound great you might be wondering why now why haven't they always been available well to understand this let's look at the process by which you draw an image to screen so for a vector asset there's two steps that we need to do when you write the vector asset in your application it's compiled down to a binary representation so at runtime your application needs to kind of load that up it needs to read this body representation and kind of inflate a model object and then it needs to perform some canvas operations to draw these individual parts to screen now if you are looking at a static vector then we can actually cache the results of this drawing operations into a bitmap to optimize subsequent water draws but if you're looking at a animated asset we can't do that contrast this to bitmaps where we simply need to decode it and then draw it to screen which can be more efficient now this is the essential trade-off I think between vectors and raster assets in the early days of Android devices were less powerful and came in fewer screen sizes and densities and as search Russ's made sense today there is much more diversity of devices out there and they're relatively more powerful so as such the benefits of vectors I think outweigh those Erastus now we're looking at vector formats you've probably come across something called SVG now SVG stands for scalable vector graphics which is the standard on the web for providing these scalable images the SVG is a old and pretty vast standard if you look at some of the things you can do in SVG you can do things like this where you provide a blur effect apply to some of the paths within the SVG or you can embed other images like an animated gif within an SVG or SVG can actually include arbitrary JavaScript now these features might not be appropriate for a constrained mobile device like an Android application SVG does however contain a path specification which is the basic drawing commands which build up most of the data inside an SVG image and now this is what Android actually supports by way of its own format which we call vector drawable so what's in the vector drawable let's take a look it's an XML file looks something like this it has a single vector node and it's made up of one or more path elements the vector itself has an intrinsic size and which is this width and height this is the size of vector would draw if you put it in a wrap content image view for example it also has a viewport size which you can think of as the canvas size that subsequent paths are defined in now the viewport size and the intrinsic size can differ but they should probably be in the same aspect ratio so what are these path commands actually do well we can think about them as controlling a virtual pen on a canvas so if we look at this kind of string of path commands you can see this M means move so move my pen to these coordinates the L stands for a line draw a line to this coordinate then an N would mean pick up the pen move it to this place and another L means draw another line so we can see with this very simple very terse syntax you can define how to draw basic shapes and with just a few commands here move lines curves arcs you can actually draw pretty much any shape now I introduced this not because I think you should be able to look at these files and read them and understand them but some basic understanding of what the vector is doing is helpful for some of the more advanced topics we'll get to you later now pass on their own don't actually do anything to actually get them to show on screen you need to either stroke them so draw their outline or fill them so fill the interior of the shape we also support a number of transformations on groups of paths so here you can rotate or translate a group of paths now this isn't particularly useful for static vectors where you could actually kind of bake in this transformation into the past themselves but this will be extremely useful when we look at animation later we also support a clip path which will mask the area that will be displayed note that clip paths aren't anti-alias so we recommend not using them too liberally here in this example of drawing some kind of camera shutter I con on the left I'm drawing it using individual paths whereas on the right I'm drawing a white square and then masking it to the shape and you can see that this can and display some artifacts so it can be a useful technique especially in combination with animation but use it sparingly lastly paths can be trimmed by which we mean you don't have to draw the entire thing you can draw a subset so say we have a line which is drawn from left or right if we apply and no trim so 0 and 1 then we try we see the whole line but if you start to apply trim valleys to the start or end we'll just draw a subset of the line you can also apply a trim offset which will move the segment of the line is being displayed and note this value can actually wrap around and to draw and draw a part at the end of part of the start so this can be extremely useful when animating which we'll look at again later lastly the root element for the whole vector has a couple of attributes you can control like the Alpha for example so you can control the author of the entire composition you can also set a tint which is extremely useful for things like iconography so in this example here I'm setting a tint to color control normal which is the standard color for icons in Android apps and as search you can define a single icon that will be dark on light screens and light on dark screens so you just have to provide at once rather than have to provide two copies you can use theme attributes for all colors in a vector both for fills and strokes so this can be extremely useful for creating very flexible assets for example you could fill a pathway of say color primary and if color primary is altered on different screens then you end up with one icon which displays differently depending on the screen it runs on both fills and strokes also support color state lists which means that you can create draw balls which will react to different states in this example and we set a different color when the heart icon is pressed or in this example here when a list item is selected we have the drawable displayed differently next factors also support gradients so you define a gradient similar to how you might first shape drawable in a separate color resource we support linear gradients where you give it a start and end XY radial gradients which just have a center point and sweep gradients so far I've been using the shorthand of defining a start or end color within the gradient definition itself alternatively if you want finer grain control you can embed individual color stops inside the gradient tag to really control the color as it goes through each gradient stop has a offset which says the progress throughout the gradient so 72% of the way here I'm drawing a specific color gradients can be extremely useful for doing things like faking shadows which affected Robles do not support so here's an example of an adaptive icon which makes liberal use of gradients to do this so here we have linear gradient on these triangles which give it a subtle depth to the icon we can also fake drop shadows or cast shadows using linear or radial gradients here and the background we're using this radial gradient on the background of these three triangle fills as well and faking a shadow here with the radial gradients behind these white circles so gradients can be extremely useful as well as for faking features like drop shadows which aren't currently supported in the format gradients also support a tile mode which is what to do if the gradient doesn't entirely fill the shape here we're using repeated so it'll go back to the start each time it reaches the end of the gradient or you can set mirrored where I'll go back and forth or you can say it's a clamp where it'll just stick at the end value and just because gradients there doesn't mean they have to actually fade through different colors here's a technique where we can use coexisting colors stops in order to get kind of a solid film now we can actually combine this technique with this tile mode in order to get rudimentary pattern support so this is just a gradient with hard color stops that is repeated and using a tar mode and we can use this in combination with animation in order to achieve some fun effects like this loading spinner and this takes advantage of the fact that we can actually draw beyond the viewport space so even though we're defining a certain viewport our path data can actually extend beyond that so if this is the viewport the actual bulb pole extends beyond that and then we animate by just moving it sideways and then repeating that infinitely and we can actually create some pretty powerful effects so in this example the sky for example is a gradient which is drawn beyond the viewport and then we animate its position up and down in order to achieve this sunrise sunset effect so how can you actually use vectors in your Android applications now the vector drawable was added in SDK 21 lollipop so if your Minister K is 21 or above you're pretty much used everywhere and you use it through the vector drawable class for the static version or animated vector drawable for the animated version but it was back ported as well in a jetpack library so the vector drawable compact or animated vector drawable compact is also available now we recommend actually preferring to use the vector durable compact class because it enables us to backport newer features added in later versions and as well as ship bug fixes so if you use app compat you will always actually get vector drawable compact the back port class on API is 21 through 23 so that we can back port these features and bug fixes do use an app in your application you can use the source compact tag on image views or text view for example supports drawable compacts for compound robles or to use this in code use app compat resources in order to inflate the images so when using vector drawables you normally have to convert them from a source usually an SVG image we mentioned the vector drawable is a subset of SVG so this really implies that there is a conversion process involved now Android studio has a converter built into it and we recommend that you use this in Android studio you can do file new vector asset and select a SVG and Android studio will convert it for you now an interesting side effect of having to convert SVG's is there's something of an ownership and decision to be made usually a designer creates your assets and hands a mater developer to be placed in the application but because of this conversion process there's a question over who actually owns that step in an ideal world the designer would convert the asset into a Android vector drawable and give it to the developer in order to be using the application unfortunately because the conversion process can be slightly involved it often falls on the developer to and perform this and as such I think this is a shame because if that process loses some information or isn't 100% correct then it's not really on the developer to spot this problem it's more the designer who owns the asset and should be able to verify the is displaying as it should do so as such I would encourage all developers to work closely with their designers in order to facilitate like true conversions so while we're talking about exporting and here's a few quick tips about how to export good SPG's and especially from sketch that will be convertible to android vector drawables the first tip is to prefer simple shapes simplicity is your friend so while you might want to keep all as much information in your source assets in your sketch files and when you're offering them in order to be able to update them later when you come to export time we recommend flattening down as much information as possible so for example if you want to create this kind of like doughnut e shape you could create this with you know one circle and then subtracting another circle for it but this would create a much more complicated asset on Android an alternative way to represent this could just be a simple circular path with a stroke additionally avoid using any shadow or blur effects in your SVG because these aren't supported in the Android format so just pretend this panel and sketch doesn't exist and lastly flatten down the shapes that you use and so while these shapes here are made up of multiple sub paths and before exporting them we recommend to flatten them down using the flatten button here in sketch in order to simplify those shapes which again will just lead to a better conversion and the last tip is to explore and artboards or slices so rather than exporting just the shape here which will actually compress and lose any white space around it from sketch you want to instead using the artboard or the slice to actually maintain the bounds around an SVG now design tools export more complicated than necessary images and as such you can use a tooling like SVG au which is a SVG optimizer and to actually simplify the asset which is going to result in more successful conversion process later sketch itself actually has a plugin which will run SVG o whenever you export an SVG it also supports and some flax and customization of what optimisations SVG o can run and i'd recommend actually updating this now the default optimisation is that the SP geo plugin uses a slightly conservative and here's a config that we've used and that will result in much more successful android conversions so here for example when you hit export you can give see it gives you this little informational pop-up telling you that it's compress the asset using SVG oh and it's saved a bunch of data lastly earn su geo is a command-line tool and it integrates with sketch but there's also a handy online version called SVG oMG which allows you to visually convert it and control which optimizations are run if you're exporting SVG's from illustrator try using the SVG tiny 1.

2 profile this actually restricts some of the features of SVG which are much more likely to convert into android vector drawables so when should you use vector a vector assets is it appropriate for all assets in your application vectors are not suitable for bitmap data like photos because there's no way to really represent this as drawing commands they are great for simple shapes and like iconography we have a few official recommendations of limiting your vector drawables to 200 by 200 dips or lint has a warning telling you to keep any individual path data to under 800 characters now the reason for this is if we think back to how vectors are rendered is these two steps they have to be inflated so had to be read from disks and turn into these model objects and then they had to be drawn we have to execute any cameras operations now both of these steps are going to be proportional to the complexity of the vector so if they are much longer or much larger each of these steps is going to take longer but I would recommend an approach of tools not rules so while these guidelines are generally helpful I'd instead recommend you to profile your applications and see if the you are encountering issues to do this we added systrace tags to the vector drawable class so you can actually profile how long both the inflation and drawing steps take so let's look at an example where developer reached out to me with this icon they were trying to convert it from an SVG into a vector drawable and encountering some of these warnings we talked about in lint so taking a look at this vector it's actually pretty complex so if we just scroll through the file there's a lot of path data in here there's about 71 individual paths inside out what's interesting is that there's a lot of colors if you look in the gutter on the left hand side here you can see there's different colors showing up but the icon is only blue and white what's going on there next up there's many many individual white paths like each of these rectangles is an individual white path parson vector drawables don't have to be contiguous which me these could actually just be defined as one path we have lots of lots of different rectangles inside that one path so there's a few opportunities for actually giving simplified information in the SVG which will result in a simpler vector drawable so how can we fix this I only have the sauce effective drawable so first step I use a tool called shape shifter to convert it back to an SVG which has enriched a tall thing around it okay then open that vector drawable in sketch and then edit some of the path data so for example all of those color paths which were obscure they actually were behind some of the white blocks and I just deleted those because they weren't necessary now you might wonder why the converter can't do this automatically well we can't just ignore information because maybe you're going to animate this and icon a later date so we can't just determined that it was not going to be visible and just remove it that's up to you it depends on what you give it so once I've made some manual edit CSV gee I don't ran it through this SVG at all in order to optimize it now it is something interesting so it actually saw all these different white boxes and merge them into a single path but it also saw the writing on that I said that's white as well I'll just merge that into a single path as well so that resulted in optimized SVG which I then re imported into Android studio using address studios converter and this is the result so it went down from 71 pass and 34 groups to this greatly simplified view now lint is still warning that one of these paths is quite complex but it's actually much much reduced from the complexity that we had before and if we actually profile this we can compare the numbers of how long it takes for both inflation and drawing so in the original we can see that we are hitting these kind of numbers and this is for a note performed on a pixel and Excel with a CPU clock pegged and then when we convert it in these manual optimizations we can see it greatly improved both the inflation and the draw time next you might consider if there are ways to simplify your asset in order to make it a convert better for example an illustrator gave me this amazing an Oreo image to convert and put into my application but when I ran this through the Android studio convertor it happily converted it but it was a huge file 116 kilobytes and the reason is if you look at this and texture there's this like nice texture on the biscuit but as we said vectors describe they depart they're going to draw using these commands so in order to provide this texture you had to draw lots and lots and lots of tiny tiny tiny little shapes and this resulted in an extremely extremely complex vector made up of lots and lots of these tiny and shapes if we just delete that texture then you end up with largely the same image without as much of the detail agreed but a much simpler file and if we convert that it's actually down to under one kilobyte in size and a much simpler asset so there may be worth a conversation with your designers saying is it appropriate is it acceptable to have a simpler representation which is going to be much much smaller file in our application so now that we know what vector drawls can do and how to convert them I want to go back to one of those opportunities we talked about of animating them later animated icons can both add a level of polish to your application as well better communicate things like state changes or make your application feel more responsive the animated vector drawable class is a very simple thin class which actually does two things it just basically points to a vector and to a number of object animators which can be applied to a path or a group a related class is the animated stateless drawable which essentially defines how to run an animated vector drawable as a transition between different drawable states as such you define static vectors for each state and then a transition to be run when moving from one state to another so what elements of a vector can you animate and the answer is pretty much anything so let's look at some examples so in this example here we have a path which is drawing an arrow and we just animate the trim start and end and properties in order to make it draw out the legs and turn into an X as well as animating the translate property on a group in order to keep it centered all these examples here again are using trim path animations so the search sue back animation for example is this one larger shape and then by controlling which parts of the shape are drawn using the trim value we can trace out different parts of the line or similarly the progress going into a tick one single shape and again uses trim to do this in this example here this is animating both the opacity and the rotation of different parts so the broken heart is made up of two shapes and then we rotate them around and fade it back in or lastly one of the most powerful features of animated vectors is actually doing something called path morphing which is where we actually animate the path of the shape that it draws you can use this both to animate the path that is drawn as well as animating clip paths which change which part of the vector is actually going to be rendered now path morphing is probably one of the most powerful but also complex parts of animated vectors you can use it to achieve some pretty complex and effects like this or even more complex like these arbitrary shape animations to do it you basically provide you target an individual vector path and give it the path data to go from and to but if you do this you may encounter an error like this where basically and the runtime is going to say that in order to do a path more if there are a couple of requirements to puff morph paths have to have both the same number and type of commands so let's take a look at what this means if you want to morph say from a small square to a large square you can take a look at the commands used to draw these so you can see that both these squares are basically made up of a move and a number of line draws and then closing the path so this morph would be compatible it has the same number and type of commands but say you want to morph instead from a square to a circle how would you do this if you look at the commands to do this you see they have different number and type of commands but this is actually a well study problem we can actually get creative in order to solve this and you do so by adding by changing the type or adding dummy points into the shapes in order to make them compatible so for example instead of using two arcs we could change the circle to be drawn with curved commands instead for curved commands likewise instead of using a simple line command this we could draw the square with curved commands as well and carefully control where the bezier control points are in order to actually draw straight lines and then we see that these shapes are compatible they have the same number anti of drawing commands so you would be able to morph between them and we can actually get as fancy as we want with this technique you can insert more dummy points inside the shapes and this will can control the kind of in-between states where it's mid morph so while we can satisfy this requirements have the same number and type of commands it can actually be tricky to author files that do this a lot of design tooling doesn't actually let you control exactly where the control points are or which order of their place in which is extremely significant for this kind of technique this is where a third-party tool called shape shifter comes in which is extremely useful so this is at all built to enable this kind of workflow so here you can see we can drag and drop in two SPG's onto the canvas and then it gives you talling in order to go in and edit the order of the points as well as placing in dummy points and in order to control this kind of morph animation then shapeshifter will allow you to export an Android animator vector drawable and which you can drop directly into your project so this is available at shapeshifter design so my goal today was that everyone should be using vector assets in their applications hopefully I've demonstrated that there are many advantages of working with vector assets and that as time is right to embrace them we've shown that the format is small and powerful and that by understanding the capabilities of what vectors can do and the tooling that you can use it helps improve your workflow if you learnt something new about vectors and you're going to use it in your app then please share this video or like and subscribe [Music].

Leave A Reply

Your email address will not be published.