SVG Rendering on Android

SVG_logo.svg

Recently I was working on a project which required me to obtain an SVG image from an API endpoint and display the image in the Android application. SVG stands for Scalable Vector Graphic, and is a way of describing an image in XML code, instead of mapping out pixels. This way the image can be scaled up and down and still look great.

SVG rendering is not supported natively on Android, so I had to set out and find a library that could help.  The first library I came across was svg-android, by Google.  I was surprised to see the library hadn’t been touched in over 3 years, but this library was the most referenced in other blog posts and Stack Overflow questions so I figured I would give it a shot.

I setup the library and implemented some very basic code following their documentation to get up and running. I placed their sample svg, android.svg, into the res/raw directory. Initially I was just getting a blank screen.  After some searching I learned I needed one extra line that wasn’t included in the documentation, which disables hardware acceleration and allows the SVG to render. After adding this line, the sample image rendered. Here is the code I used:

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);

   ImageView imageView = new ImageView(this);
   imageView.setBackgroundColor(Color.WHITE);

   SVG svg = SVGParser.getSVGFromResource(getResources(), 
                                          R.raw.android);

   imageView.setImageDrawable(svg.createPictureDrawable());

   // ***Not in Doc*** Disable HW acceleration for SVGs
   imageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

   setContentView(imageView);
}

And here is what I saw:

Screen Shot 2015-03-20 at 5.20.16 PM

Yay! Next, I tried loading up a sample of the image I would eventually be loading up for the project.  Unfortunately, I just got a big black-filled shape of the image.  The project image was a much more complex SVG than the above android robot.  After some researching I learned that the svg-android library only supports a ‘subset’ of the SVG standard. I still wasn’t sure what exactly svg-android was or wasn’t supporting, but I did know that it wasn’t working for this more complex SVG. Back to the drawing board.

I found another Google SVG library, called androidsvg.  This library was much more recently published (summer 2014, nice!) and  I decided to use the beta version.  This library approaches SVG display a bit differently. The first library (svg-android) renders your SVG into a drawable, which you display in a regular android ImageView.  This second library (androidsvg) creates a view SVGImageView which extends from android’s ImageView.  Here is the code I used to load up the android.svg (also in res/raw) for this new library:

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);

   try {
      SVG svg = SVG.getFromResource(this, R.raw.android);

      SVGImageView svgImageView = new SVGImageView(this);
      svgImageView.setSVG(svg);
      svgImageView.setLayoutParams(
         new ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, 
            ViewGroup.LayoutParams.MATCH_PARENT));
   
      RelativeLayout layout = 
          (RelativeLayout) findViewById(R.id.layout_card);

      layout.addView(svgImageView);

   } catch (SVGParseException e){
      e.printStackTrace();
   }
}

And here is what I saw:

Screen Shot 2015-03-20 at 5.17.21 PM

Great.  I then tested the project image with this library and it worked as well!  This library definitely supported more of the SVG standard.  Again, I couldn’t locate specifics of what precisely this library does and does not support.  (It would be great to know this information, so I could send it to whoever was creating my SVGs.)

I don’t usually care to setup views programmatically unless necessary, and this library claims to allow you to setup an XML SVGImageView element as well.  I tried several different ways (and also tried the non-beta library), but never was able to get that working.

When setting up this view programmatically, I made sure to also set ids on the views using ids.xml, so that our automated QA team could access the views with calabash.  Unfortunately, these efforts were for not, because calabash cannot see any item on screen that is of type SVGImageView! Bummer.  It doesn’t even classify it as a generic view, and you cannot locate it by id. It is as if the view simply doesn’t exist.

Ultimately, the lack of XML layout and calabash support weren’t deal breakers for me, so I chose to use this library in the project.

Have you ever rendered SVG images on Android? What library did you use?

This entry was posted in Android, UI. Bookmark the permalink.

4 Responses to SVG Rendering on Android

  1. Umer Iftikhar says:

    Hi,

    Could you please tell me how can I move the image up and down and sideways using,
    layout.addView(svgImageView);
    I want my image to be below my simple layout.

    Thanks in advance. 🙂

  2. Pingback: 2015 Recap | KioDev

  3. Grafix says:

    Its working if your svg file is inside the project folder. What if you want to load the svg file into imageview in a specific folder location. Ex External Environment or in SD card. How to achieve that thing. Can you help me how to figure it out.

  4. You could probably use a single background svg image that traced the shape you want, as in just use the larger div with a background image.

Leave a Reply

Your email address will not be published. Required fields are marked *