Today I'd like to share with you a technique I used to create my map apps. I've never heard of anyone using it before, even though I find it quite simple. It lets you use SVG images inside your Android apps without any external libraries or extra code. What is more, the images obtained this way load instantly and can be magnified indefinitely without any loss of quality. Sounds interesting? Keep on reading to find out how it actually works.
It all began with my frustration with bitmaps, which caused OutOfMemoryErrors when used in too high resolution or zoomed in too much. I decided to switch to vector images, which unfortunately are not supported out of the box by Android. You have to use SVG parsing libraries that sometimes do not support certain features (text, gradients, symbols), contain bugs, and take a couple of seconds to create a medium-sized image.
After some time an idea came to me - what if I transformed an SVG loading library so that it printed Java code instead of executing it and returning a Drawable instance? It sounded very easy and turned out to require much more work than I initially expected, but the final result was great. All I needed to do was take the printed Java code and paste it inside a new class.
If it still sounds a little abstract to you, I created a sample app that uses an image generated this way. It basically just shows a vector-based creature and lets you magnify it up to 16 times (see the screenshots on the right). You can download it for free from Google Play and test it yourself. I'm making its full source code available as well, so feel free to take a look at it.
If you're wondering what kind of apps you could create using vector images, go and see my Milan Metro. It's a great example of simplicity and performance (just compare it with other similar apps!).
Apart from that, vector graphics is great for UI elements, because it scales without losing quality on all devices and screen densities. There is no need to create separate versions of resources for mdpi, hdpi, xhdpi, xxhdpi, etc.
Another good example I can think of are splash screens. What if you could make sure that they look pretty, regardless of the screen resolution and size, taking much less space at the same time? Wouldn't that be awesome?!
If you'd like to have your SVG pictures transformed into Drawables, check out my Fiverr gig - I can do it for you. You can also contact me via email (bartas [dot] wesolowski [at] gmail [dot] com) if you have a bigger task for me or if you want more instructions on how to implement a similar thing yourself.
nice. And I'd like to reference it in g+ community: https://plus.google.com/u/1/communities/100642514181753820652
ReplyDeleteGreat idea! Have you prepared a tool which would be able to do the generic conversion?
ReplyDeleteI guess it would be possible to extend the idea with the possibility of applying typical transformation on the vectors before rendering like rotation, mirroring, etc.
No, I didn't create any tools for it, but I still think you can achieve the same result without much effort. I basically just appended all the drawing instructions to one StringBuilder, then stopped the code execution at a breakpoint and copy-pasted the generated code to a separate file. Not very clean, but it was working fine. Later I even enhanced it a little by separating sequences that were repeating themselves into functions.
ReplyDeleteI was thinking about creating a tool for it so that other people could use it as well, but I didn't see enough interest. Perhaps if more people write to me with the same request, I'll rethink it once again.
Thanks for the reply. I thought you had prepared some internal tool for this purpose.
DeleteIf you don't mind I steal your idea and implement a tool: I need it for my little game anyway. I am going to release the sources and credit you for your idea.
Sure, go for it and let me know when you finish. I'll be glad to share it with my readers.
DeleteFor the readers' benefit, the tool inspired by this post is available here:
ReplyDeletehttps://github.com/racsdragon/android-svg-code-render