Hi All,

It turns out that there are some Android system bugs affecting VectorDrawable rendering on Android 6, see Bug 1325929 [1]. This results in some icons being distorted. (As far as I can tell this only affects icons that include curved paths, but I'm no real SVG expert...).


The distorted icons had been prepared using the Android Studio VectorDrawable converter (I was using Android Studio 2.2.3, I haven't tested 2.3 yet). The workaround was to use an alternative online converter, which seems to produce VectorDrawable's that don't trigger rendering bugs:

http://inloop.github.io/svg2android/ (Warning: it claims to not be compatible with FF)

This converter also adds the 'android:fillType="evenOdd"' attribute, which is only supported on Android 24+. I simply removed it, and the icons rendered without any issues; I'd recommend manual testing on a case by case basis since this might not work for all icons.


There were still minor differences in the rendering of one of the icons (the legs of one part of the share icon were slightly fatter, but not as badly as shown in the aforementioned bug). I was able to fix this by importing the original SVG into an editor, followed by ungrouping and regrouping the image components (in addition to then using the same online converter).


Cheers,

    Andrzej


[1] https://bugzilla.mozilla.org/show_bug.cgi?id=1325929


On 12/2/16 12:28 PM, Andrzej Hunt wrote:
Hi All,

A while back we landed initial support for VectorDrawable's (Bug 1309821 [1]).

VectorDrawable is an Android-specific XML based format that's largely similar to SVG, with some limitations around gradients and other SVG features. Using VectorDrawable's in place of png's should be helpful in minimising APK size - I therefore encourage using them whenever possible.

This support isn't complete - VectorDrawable's aren't a drop-in replacement for existing resources for a number of reasons, as detailed below.


== How and where to use VectorDrawable's ==

VectorDrawable support on 4.X devices is provided by the support library (Android framework only supports it on 5 and higher). It's still possible to manually load VectorDrawable's in locations where support isn't automatically provided, which means it's still be possible to use them with a little bit of tweaking.

1. Support library and AppCompat code handles many cases
   automatically.

2. ImageView: use the app:srcCompat attribute instead of android:src
   (Under the hood: the support library replaces ImageView with
   AppCompatImageView during layout inflation, i.e. AppCompatImageView
   handles the VectorDrawable's too).

3. Menu resources, when using Support Library widgets (e.g.
   NavigationView): support is automatic. (Support for the main
   app menu has also been added manually, using {4}.)

4. Otherwise: manual loading - use:
   ResourceDrawableUtils.getDrawable()

Using them in xml (e.g. as drawableLeft|Right|etc), as part of buttons, TextView's etc., is not supported.

(In theory it's possible to completely override all resource loading, in order to avoid any special VectorDrawable handling, by setting
AppCompatDelegate.setCompatVectorFromSourcesEnabled(true). However
this is reported to increase memory usage, and can break configuration updates. We probably want to avoid that as far as possible, especially given the special configuration handling code we have as part of our multilocale support. I didn't have much success when testing this locally either.)


== Generating VectorDrawable's ==

The best tool I've found so far is Android Studio's "Vector Asset Studio", which is found under |File->New->Vector Asset| in AS. This allows you to import (and preview) an existing SVG file.

If using the Vector Asset Studio:
1. Select "local SVG" on the first screen to import an SVG.
2. Select "../base/resources" as the |Res Directory| on the second
   screen in order for it to land in the correct location.


== When not to use VectorDrawable ==

The official recommendation is to only use these for images up to 200 x 200dp, and also to avoid overly complicated images - all for performance reasons [2]. (Vector Images are seemingly rendered to a local bitmap buffer, before being used in the usual Android rendering
process.)


== Related APK size considerations: webp conversion ==

As of Android 4.0 it's possible to use webp for raster images. This generally provides better compression than png, however webp conversion can introduce artifacts (mostly visible along edges) so care is required - tweaking the conversion/compression quality can result in acceptable images. On Android 4.0 - 4.2.0 only non-transparent webp images are supported, hence we need to avoid transparent images for now.

I've documented the conversion process on the wiki [3].

(Most of our larger images don't require a transparent background - one possibility is setting a solid background and removing the alpha channel to allow for webp conversion - this is all described on the aforementioned wiki page).

== Summary ==

- Use VectorDrawable for all icons, and most smaller images.
- Use webp for most other images, unless they must contain transparency.
- Use png only as a last resort.


Cheers,

    Andrzej


[1] https://bugzilla.mozilla.org/show_bug.cgi?id=1309821

[2] https://developer.android.com/studio/write/vector-asset-studio.html#when

[3] https://wiki.mozilla.org/Mobile/Fennec/Android/png_optimisation

_______________________________________________
mobile-firefox-dev mailing list
mobile-firefox-dev@mozilla.org
https://mail.mozilla.org/listinfo/mobile-firefox-dev

Reply via email to