a-student / BetterVectorDrawable

The VectorDrawable implementation for Android 4.0+
151 stars 22 forks source link

@Deprecated

Official Android Support Library 23.2 added support for Vector Drawables and Animated Vector Drawables. Please, use that. This lib is still usable, but it is no longer maintained.

BetterVectorDrawable

The VectorDrawable implementation for Android 4.0+ (API level 14 or greater).

Alternative to the automatic generation of PNGs from vector drawables at build time by Android Plugin for Gradle 1.5.0+. The lib saves APK size and properly supports SVG’s fill rule (see below).

Xamarin version of BetterVectorDrawable can be found here.

Keywords: vector drawable, support library, compat, svg

Attaching the library

JCenter

The lib is deployed to the JCenter repository, so just add this line to the build.gradle dependencies section:

compile 'com.bettervectordrawable:lib:0.8+'

In addition, you will need to disable automatic generation of PNGs at build time by adding generatedDensities = [] line to the defaultConfig section:

defaultConfig {
    generatedDensities = []
    …
}

Usage

Inflating

Drawable drawable = VectorDrawableCompat.inflate(getResources(), R.drawable.your_vector);

// or if resource interception is enabled (see below for how to enable)
Drawable drawable = getResources().getDrawable(R.drawable.your_vector);

There is an overload of the first method with a boolean parameter, which allows to force system handling of vector drawables on Android 5.0+. However, using this overload is not recommended, because system implementation of VectorDrawable does not support some extra features, like path’s fillType attribute (see below).

The second method is advised to always use because it allows the system to cache the drawable and hence is more efficient.

Referencing vector drawables from other XML resources

It is possible to reference vector drawables from other drawable or layout XML resources as regular drawables. For this feature to work, you need to enable resource interception.

Extend the Application class and override the onCreate() method. Do not forget to modify AndroidManifest.xml accordingly (see the demo app).

Call

VectorDrawableCompat.enableResourceInterceptionFor(getResources(), …);

from the onCreate method. The last parameter is a list of vector resource IDs for which interception must be enabled.

There are three ways to obtain the list. If you are not sure what way to choose, try to measure the performance of the each method.

Very convenient, but relatively slow

int[] ids = VectorDrawableCompat.findAllVectorResourceIdsSlow(getResources(), R.drawable.class);
VectorDrawableCompat.enableResourceInterceptionFor(getResources(), ids);

This method scans through all drawable XML resources and ensures that each returned resource has vector data inside. Usually it is OK to use this method by default. Nevertheless, it may increase application startup time on old devises if the app has many drawable resources of any type.

Less convenient, but faster

int[] ids = VectorDrawableCompat.findVectorResourceIdsByConvention(getResources(), R.drawable.class, Convention.RESOURCE_NAME_HAS_VECTOR_SUFFIX);
VectorDrawableCompat.enableResourceInterceptionFor(getResources(), ids);

This method uses resource naming convention to find vector resources. It relies on that every vector resource name matches vector_* pattern or *_vector pattern, or both. This can be controlled by the resourceNamingConvention parameter.

The fastest, but inconvenient

VectorDrawableCompat.enableResourceInterceptionFor(getResources(),
    R.drawable.your1_vector,
    R.drawable.your2_vector,
    R.drawable.your3_vector);

Just enumerate vector drawable resource IDs manually.

Converting SVGs to vector drawables

When parsing XML resources, Android ignores XML attributes that aren’t supported by the current device.

This is why you have to duplicate unsupported android: attributes in the vector drawable XMLs. For example:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:better="http://schemas.android.com/apk/res-auto"
    android:width="100dp"
    android:height="100dp"
    android:viewportHeight="100"
    android:viewportWidth="100"
    better:viewportHeight="100"
    better:viewportWidth="100">
…

For a complete list of attributes, which must be duplicated, see attrs.xml (duplicate attributes do not have android: prefix).

To make it easier for you, use SVG to VectorDrawable Converter. To produce vector drawables for this lib, append to the converter command the --lib BetterVectorDrawable argument like

svg2vd.exe -i * --lib BetterVectorDrawable

This command creates vector drawables containing additional attributes that are understandable by the lib.

Converting vector drawable to Bitmap

The lib contains the util class that allows you to convert almost any drawable to a Bitmap. Read more.

Path’s fillType attribute

The lib additionally supports specifying better:fillType attribute on a path. This gives you ability to control how the inside of the path is determined. It corresponds to the fill-rule attribute in SVG and accepts two values: winding (nonzero in SVG) and even_odd (evenodd in SVG).

Issues

If you have any problems with the lib, please create an issue on GitHub (https://github.com/a-student/BetterVectorDrawable/issues/new) and explain the reproducing steps.

License

Apache 2.0