define('DISALLOW_FILE_EDIT', true);{"id":4342,"date":"2014-02-19T18:39:58","date_gmt":"2014-02-19T23:39:58","guid":{"rendered":"http:\/\/www.unfocus.com\/?p=4342"},"modified":"2014-05-14T23:47:02","modified_gmt":"2014-05-15T03:47:02","slug":"svgview-for-xamarin-android","status":"publish","type":"post","link":"http:\/\/www.unfocus.com\/2014\/02\/19\/svgview-for-xamarin-android\/","title":{"rendered":"SVGView for Xamarin.Android"},"content":{"rendered":"
Instead of making dozens of PNG files<\/a> for all the various screen sizes<\/a> for icon assets, I wanted to use vector graphics<\/a> (such as SVG<\/a>) in an\u00a0Android<\/a> app I’m building<\/a> with Xamarin.Android<\/a>. There is a tool for generating images<\/a>, and that’s better than nothing, but SVG is even easier, and I’m all about easier. I thought this would be relatively easy to do, but it turns out Android has no built in support for vector image formats.<\/p>\n Xamarin<\/a> has a nice binding project and sample<\/a> for using an SVG library (I think it wraps SVG-Android on GitHub<\/a>) in Android apps, but it wasn’t clear how to use that, and there was an annoying gotcha I hit along the way, that I thought I’d document here.<\/p>\n There are two projects in the sample solution. One is the library project, and the other is a sample project, with sample art that you can build to see it working. What we want to do is build the library, and then copy the necessary components into our own Android app project. Here’s how to do that using Xamarin Studio<\/a>.<\/p>\n That’s it! Those two files are all you need. Now you can create an SVGView class, and use that in your axml layouts. Here’s a quick and dirty example of the class:<\/p>\n [csharp]using System; namespace unFocus \t\tpublic SVGView (Context context) : \t\tpublic SVGView (Context context, IAttributeSet attrs) : \t\tpublic SVGView (Context context, IAttributeSet attrs, int defStyle) : \t\tvoid Initialize () \t\tvoid Initialize (IAttributeSet attrs) \t\tvoid setupSVG () \t\t\tif (null == SVGSrc) And in values\/attrs.xml:<\/p>\n [xml]<?xml\u00a0version="1.0"\u00a0encoding="UTF-8"\u00a0?> Now you can create SVGViews in axml using:<\/p>\n [xml]<unFocus.SVGView SVG files go in the Assets folder, in whatever tree you want. In this example, they are in Assets\/svg\/. Build action for svg files is “AndroidAsset,” which should be the default.<\/p>\n There is an irritating gotcha, that’ll have you tearing your hair out if you don’t know about it.<\/p>\n SVG files MUST have width and height attributes on the root element to work with this library. If you don’t have them, and Adobe Illustrator CC doesn’t add them by default, the lib will fail with cryptic error messages. The fix is easy enough, just open the SVG in Xamarin and add width and height attributes. There will already be a viewBox attribute with the correct attributes (viewBox=”0 0 70 70″ <– the second two, width and height). You’ll need to add these: width=”70px” height=”70px”.<\/p>\n Update:<\/strong> One other thing I forgot to mention – this didn’t work on the Xamarin Alpha for some reason. The SVGAndroid binding was failing if I remember correctly (at least that’s where the runtime\u00a0 errors seemed to originate). So if you are having trouble getting this to work, it might be something in the Alpha channel.<\/p>\n Update 2:<\/strong> What I’ve showed you here will work, but some folks on the Xamarin forums suggest there may be advantages to including third party code in alternative ways (like including an entire project, etc.). Have a read.<\/a><\/p>\n Update 3:<\/strong> SVG-Android won’t work<\/a> under hardware acceleration<\/a>, which is enabled by default in apps targetting Android 3.0 and newer. You just get a blank space. The easiest way around this is to set the Application, Activity, or the specific view you are working on to use software acceleration.<\/p>\n I modified the SVGView example above to do this automatically, but you can also do it yourself (using the code above) or by setting the android:layerType=”software” on the specific view (or somethings its parent).<\/p>\n This is worth knowing about because other types of drawables (such as animations) seem to display other types of incompatibilities with hardware acceleration (such as fuzzy low resolution renderings), and setting software mode can fix it.<\/p>\n Enjoy!<\/p>\n","protected":false},"excerpt":{"rendered":" Instead of making dozens of PNG files for all the various screen sizes for icon assets, I wanted to use vector graphics (such as SVG) in an\u00a0Android app I’m building with Xamarin.Android. There is a tool for generating images, and that’s better than nothing, but SVG is even easier, and I’m all about easier. I … Continue reading “SVGView for Xamarin.Android”<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[63,180],"tags":[225,182,30,226],"_links":{"self":[{"href":"http:\/\/www.unfocus.com\/wp-json\/wp\/v2\/posts\/4342"}],"collection":[{"href":"http:\/\/www.unfocus.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.unfocus.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.unfocus.com\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.unfocus.com\/wp-json\/wp\/v2\/comments?post=4342"}],"version-history":[{"count":3,"href":"http:\/\/www.unfocus.com\/wp-json\/wp\/v2\/posts\/4342\/revisions"}],"predecessor-version":[{"id":4388,"href":"http:\/\/www.unfocus.com\/wp-json\/wp\/v2\/posts\/4342\/revisions\/4388"}],"wp:attachment":[{"href":"http:\/\/www.unfocus.com\/wp-json\/wp\/v2\/media?parent=4342"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.unfocus.com\/wp-json\/wp\/v2\/categories?post=4342"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.unfocus.com\/wp-json\/wp\/v2\/tags?post=4342"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}\n
\n<\/li>\n
\nusing System.Collections.Generic;
\nusing System.Linq;
\nusing System.Text;
\nusing Android.App;
\nusing Android.Content;
\nusing Android.OS;
\nusing Android.Runtime;
\nusing Android.Util;
\nusing Android.Views;
\nusing Android.Widget;
\nusing Com.Larvalabs.Svgandroid;<\/p>\n
\n{
\n\tpublic class SVGView : ImageView
\n\t{
\n\t\tprotected string svgSrc;
\n\t\tpublic string SVGSrc {
\n\t\t\tget {
\n\t\t\t\treturn svgSrc;
\n\t\t\t}
\n\t\t\tset {
\n\t\t\t\tsvgSrc = value;
\n\t\t\t\tsetupSVG ();
\n\t\t\t}
\n\t\t}<\/p>\n
\n\t\t\tbase (context)
\n\t\t{
\n\t\t\tInitialize ();
\n\t\t}<\/p>\n
\n\t\t\tbase (context, attrs)
\n\t\t{
\n\t\t\tInitialize (attrs);
\n\t\t}<\/p>\n
\n\t\t\tbase (context, attrs, defStyle)
\n\t\t{
\n\t\t\tInitialize (attrs);
\n\t\t}<\/p>\n
\n\t\t{
\n\t\t}<\/p>\n
\n\t\t{
\n\t\t\tvar a = Context.ObtainStyledAttributes(attrs, Resource.Styleable.SVGView);
\n\t\t\tSVGSrc = a.GetString(Resource.Styleable.SVGView_svgSrc);
\n\t\t\ta.Recycle ();
\n\t\t}<\/p>\n
\n\t\t{
\n\t\t\t\/\/ svg-android doesn’t work in hardware mode, so set software
\n\t\t\tSetLayerType (LayerType.Software, null);<\/p>\n
\n\t\t\t\treturn;
\n\t\t\tSVG svg = SVGParser.GetSVGFromAsset (Context.Assets, SVGSrc);
\n\t\t\tSetImageDrawable (svg.CreatePictureDrawable ());
\n\t\t\tInvalidate ();
\n\t\t}
\n\t}
\n}[\/csharp]<\/p>\n
\n <resources>
\n \u00a0\u00a0\u00a0\u00a0<declare-styleable\u00a0name="SVGView">
\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<attr name="svgSrc"\u00a0format="string"><\/attr>
\n \u00a0\u00a0\u00a0\u00a0<\/declare>
\n <\/resources>[\/xml]<\/p>\n
\n \u00a0\u00a0 android:svgSrc="svg\/somesvgfile.svg"
\n \u00a0\u00a0 android:layout_width="58.0dp"
\n \u00a0\u00a0 android:layout_height="58.0dp"
\n \u00a0\u00a0 android:id="@+id\/icon" \/>[\/xml]<\/p>\n