Typically, the design of the application is drawn in a vector editor (for example, Sketch), but the typical image format in an Android application is raster (usually PNG). When developing an application, it is necessary for each vector image to do the tedious work of making a set of raster images for different screen densities. The number of such sets can be up to six by the number of possible densities: ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi (density xxxhdpi is needed only for the application icon). When layout, sometimes you have to specify in the markup explicit dimensions for the image, which may require rescaling the bitmap, and this, in turn, will certainly lead to the appearance of artifacts. In addition, the presence of several sets of pictures adversely affects the size of the output apk.
All solve these problems in different ways: someone is trying to
connect the SVG-library to the project, someone
generates cutting with the help of the utility.
As it seems to me, the most appropriate solution is to stop using raster graphics in the application in favor of vector graphics. In this case, I would like to maximize the use of system capabilities. In Android 5.0,
VectorDrawable appeared - vector format support for images that are placed as resources with the xml extension in the drawable folder. Such images can be referenced in the usual way from the XML markup.
')
Using VectorDrawable would be a great solution if it were not for the need to support devices with Android 4.0+, which are the majority. VectorDrawable is not in the support library and it is not known when it will appear there (although a start has been made). But do not be sad: there is a wonderful open source
BetterVectorDrawable library with the Apache 2.0 license, which actually transfers VectorDrawable to Android 4.0+, providing the same interface, and allows you to use the system VectorDrawable on Android 5.0+ if necessary. It should be noted that there are a couple of similar libraries, but they are not worth your attention, because they do not give full reference to vector drawable resources from the markup.
Unfortunately, Android developers have not provided support for VectorDrawable
gradients ,
textures ,
masks . This is a small problem, but this should be remembered when drafting an application. If it is impossible to refuse these elements, then it is possible to use raster graphics /
shape drawable in certain places, mainly switching to a vector.
So, to switch to the vector image format in the application:
- Connect the BetterVectorDrawable library to the application
- To unload from the vector editor images in SVG-format
- Using the converter, convert them all at once to the vector drawable XML format
- Put the resulting files into the res / drawable application directory
- Use vector images in markup and in code as normal resources.
- Profit
BetterVectorDrawable library
We connect library
To connect the library to the application, it is enough to add one line in the
dependencies
section of the
build.gradle file located in the application module directory:
dependencies { … compile 'com.bettervectordrawable:lib:0.4+' }
The library is distributed through the JCenter repository, which is used by default in new Android Studio projects.
If you created a project a long time ago, then you may be using the Maven Central repository. To check this, you need to look for line entries in the
build.gradle files
.
mavenCentral()
and add next to her
jcenter()
Turn on resource interception
The library must pass a list of identifiers of vector resources so that it understands which of them are vector drawable. BetterVectorDrawable will intercept calls to them and create
VectorDrawable
instances.
Since the list needs to be
onCreate()
once, it is best to do this in the
onCreate()
method of the
Application
class, for which you will have to create its successor:
package com.bettervectordrawable.demo; import android.app.Application; import com.bettervectordrawable.VectorDrawableCompat; public class App extends Application { @Override public void onCreate() { super.onCreate();
And indicate this successor in the application manifest:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.bettervectordrawable.demo"> <application android:name=".App" …
There are three ways to transfer the list: convenient, quick and manual.
Convenient way
int[] ids = VectorDrawableCompat.findAllVectorResourceIdsSlow(getResources(), R.drawable.class); VectorDrawableCompat.enableResourceInterceptionFor(getResources(), ids);
The
findAllVectorResourceIdsSlow
method scans all drawable XML resources and makes sure that each returned resource is a vector drawable. Developers advise using this method by default, however, this is the least productive way, i.e. On older devices, the launch time of the application may increase significantly.
On Google Nexus 5, in the application with 400 vector resources,
findAllVectorResourceIdsSlow
performs in less than 150 ms.
Quick way
int[] ids = VectorDrawableCompat.findVectorResourceIdsByConvention(getResources(), R.drawable.class, Convention.ResourceNameHasVectorSuffix); VectorDrawableCompat.enableResourceInterceptionFor(getResources(), ids);
The
findVectorResourceIdsByConvention
method implies that the names of all vector resources begin with
vector_ or end with
_vector . The naming convention must be specified using the
resourceNamingConvention
parameter.
On Google Nexus 5, in an application with 400 vector resources,
findVectorResourceIdsByConvention
performs in less than 20 ms.
Manual mode
VectorDrawableCompat.enableResourceInterceptionFor(getResources(), R.drawable.your1_vector, R.drawable.your2_vector, R.drawable.your3_vector);
A list of all identifiers of vector images is simply transmitted. 0 ms
Use vector drawable
In the code:
Drawable drawable = getResources().getDrawable(R.drawable.your_vector);
Or from the markup:
<View android:layout_width="210dp" android:layout_height="210dp" android:background="@drawable/your_vector" />
As you can see, everything is simple.
If you have any questions, you can ask them to me or see the
demo application . It is better to report problems with the library to developers on
GitHub .
In the next part, we will discuss converting images from SVG to vector drawable XML.