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