📜 ⬆️ ⬇️

VectorDrawable - Part One

I bring to your attention the translation of the article " VectorDrawables - Part 1 " from the website blog.stylingandroid.com.


On duty, I needed to somehow deal with vector graphics. During the search, I stumbled upon a series of articles called “VectorDrawable” in the blog post https://blog.stylingandroid.com/ . I, of course, did not find answers to all the questions that interest me, but I really liked the articles because of their consistency and precisely verified amount of necessary material. I decided to share the translation of these articles with the inhabitants of Habr.


I did not translate the name, activity, bitmap, and the like, because I think it is easier to perceive information that way, because the developers, by virtue of their profession, almost never use these words in the Russian version. The following is a translation:


One of the really interesting new features in Lollipop is the inclusion of VectorDrawable and its related classes, which provide extremely powerful new features for adding complex vector graphics (it makes it much easier to scale images regardless of screen size and density than bitmaps), as well as provides several powerful tools for animating these. In this series of articles we will look at some of the advantages that they give us. Also consider how you can get really impressive results from a relatively small amount of code.


Vector graphics are a way to describe graphic elements using geometric shapes. They are particularly well suited for graphic elements created in applications such as Adobe Illustrator or Inkscape, where simple geometric shapes can be combined into much more complex elements. Working with raster graphics, on the other hand, determines the color value for each pixel and is particularly well suited for photos. The big advantage of using vector graphics (as appropriate) is that the images are rendered in runtime and the dimensions are automatically calculated depending on the pixel density. Thus it turns out a clear picture with smooth lines, regardless of the capabilities of the device. Vector images, as a rule, occupy a much smaller memory size than their raster counterpart. However, vector images require more computational power to render, which can be a problem with a large number of complex graphic elements.


Vector graphics in android was implemented using a new class - VectorDrawable, which was introduced in Lollipop. This means that for graphic elements that are well suited for a vector representation, we can replace bitmaps in the mdpi, hdpi, xhdpi, xxhdpi, and xxxhdpi folders with one VectorDrawable in the Drawable folder, which is likely to take even less disk space than a bitmap for mdpi.


To demonstrate this, let's consider the following svg file (you can find it at https://code.google.com/archive/p/svg-android/downloads ):


image


This svg-file is 2265 bytes, if we draw it in a bitmap with dimensions of 500 x 500 pixels and save as png, then it will take 13272 bytes, plus we will need to use several such pictures for different screen densities. But SVG is not the same as VectorDrawable, so we cannot use it directly. However, VectorDrawable supports some SVG elements. The main components that we will use from our SVG is the path. Let's look at the SVG source code:


android.svg
<?xml version="1.0" encoding="utf-8"?> <!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948) --> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="500px" height="500px" viewBox="0 0 500 500" enable-background="new 0 0 500 500" xml:space="preserve"> <g id="max_width__x2F__height" display="none"> <path display="inline" d="M499.001,1v498H1V1H499.001 M500.001,0H0v500h500.001V0L500.001,0z"/> </g> <g id="androd"> <path fill="#9FBF3B" d="M301.314,83.298l20.159-29.272c1.197-1.74,0.899-4.024-0.666-5.104c-1.563-1.074-3.805-0.543-4.993,1.199 L294.863,80.53c-13.807-5.439-29.139-8.47-45.299-8.47c-16.16,0-31.496,3.028-45.302,8.47l-20.948-30.41 c-1.201-1.74-3.439-2.273-5.003-1.199c-1.564,1.077-1.861,3.362-0.664,5.104l20.166,29.272 c-32.063,14.916-54.548,43.26-57.413,76.34h218.316C355.861,126.557,333.375,98.214,301.314,83.298"/> <path fill="#FFFFFF" d="M203.956,129.438c-6.673,0-12.08-5.407-12.08-12.079c0-6.671,5.404-12.08,12.08-12.08 c6.668,0,12.073,5.407,12.073,12.08C216.03,124.03,210.624,129.438,203.956,129.438"/> <path fill="#FFFFFF" d="M295.161,129.438c-6.668,0-12.074-5.407-12.074-12.079c0-6.673,5.406-12.08,12.074-12.08 c6.675,0,12.079,5.409,12.079,12.08C307.24,124.03,301.834,129.438,295.161,129.438"/> <path fill="#9FBF3B" d="M126.383,297.598c0,13.45-10.904,24.354-24.355,24.354l0,0c-13.45,0-24.354-10.904-24.354-24.354V199.09 c0-13.45,10.904-24.354,24.354-24.354l0,0c13.451,0,24.355,10.904,24.355,24.354V297.598z"/> <path fill="#9FBF3B" d="M140.396,175.489v177.915c0,10.566,8.566,19.133,19.135,19.133h22.633v54.744 c0,13.451,10.903,24.354,24.354,24.354c13.451,0,24.355-10.903,24.355-24.354v-54.744h37.371v54.744 c0,13.451,10.902,24.354,24.354,24.354s24.354-10.903,24.354-24.354v-54.744h22.633c10.569,0,19.137-8.562,19.137-19.133V175.489 H140.396z"/> <path fill="#9FBF3B" d="M372.734,297.598c0,13.45,10.903,24.354,24.354,24.354l0,0c13.45,0,24.354-10.904,24.354-24.354V199.09 c0-13.45-10.904-24.354-24.354-24.354l0,0c-13.451,0-24.354,10.904-24.354,24.354V297.598z"/> </g> </svg> 

We will understand a little. There are some attributes of the parent element that define the size of 500x500, there is an element (group) that defines the boundaries - we will ignore it. There is another element with id = “android”. This is the logo image that we need. It consists of six elements that define the head, the right eye, the left eye, the left arm, the body and the legs, the right arm. The “fill” attribute defines the fill color (and we can see that they are all green, with the exception of the eyes, which are filled with white), and the “d” attribute contains the route of the lines that make up the element. For those who want to understand the element in more detail, you should study the SVG Path Specification , but this is not important for this article, because we can simply take them as they are and use them in our VectorDrawables.

So let's create our VectorDrawable:


res / drawable / android.xml
 <?xml version="1.0" encoding="utf-8"?> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:viewportWidth="500" android:viewportHeight="500" android:width="500px" android:height="500px"> <group android:name="android"> <path android:name="head" android:fillColor="#9FBF3B" android:pathData="M301.314,83.298l20.159-29.272c1.197-1.74,0.899-4.024-0.666-5.104c-1.563-1.074-3.805-0.543-4.993,1.199L294.863,80.53c-13.807-5.439-29.139-8.47-45.299-8.47c-16.16,0-31.496,3.028-45.302,8.47l-20.948-30.41c-1.201-1.74-3.439-2.273-5.003-1.199c-1.564,1.077-1.861,3.362-0.664,5.104l20.166,29.272c-32.063,14.916-54.548,43.26-57.413,76.34h218.316C355.861,126.557,333.375,98.214,301.314,83.298" /> <path android:name="left_eye" android:fillColor="#FFFFFF" android:pathData="M203.956,129.438c-6.673,0-12.08-5.407-12.08-12.079c0-6.671,5.404-12.08,12.08-12.08c6.668,0,12.073,5.407,12.073,12.08C216.03,124.03,210.624,129.438,203.956,129.438" /> <path android:name="right_eye" android:fillColor="#FFFFFF" android:pathData="M295.161,129.438c-6.668,0-12.074-5.407-12.074-12.079c0-6.673,5.406-12.08,12.074-12.08c6.675,0,12.079,5.409,12.079,12.08C307.24,124.03,301.834,129.438,295.161,129.438" /> <path android:name="left_arm" android:fillColor="#9FBF3B" android:pathData="M126.383,297.598c0,13.45-10.904,24.354-24.355,24.354l0,0c-13.45,0-24.354-10.904-24.354-24.354V199.09c0-13.45,10.904-24.354,24.354-24.354l0,0c13.451,0,24.355,10.904,24.355,24.354V297.598z" /> <path android:name="body" android:fillColor="#9FBF3B" android:pathData="M140.396,175.489v177.915c0,10.566,8.566,19.133,19.135,19.133h22.633v54.744c0,13.451,10.903,24.354,24.354,24.354c13.451,0,24.355-10.903,24.355-24.354v-54.744h37.371v54.744c0,13.451,10.902,24.354,24.354,24.354s24.354-10.903,24.354-24.354v-54.744h22.633c10.569,0,19.137-8.562,19.137-19.133V175.489H140.396z" /> <path android:name="right_arm" android:fillColor="#9FBF3B" android:pathData="M372.734,297.598c0,13.45,10.903,24.354,24.354,24.354l0,0c13.45,0,24.354-10.904,24.354-24.354V199.09c0-13.45-10.904-24.354-24.354-24.354l0,0c-13.451,0-24.354,10.904-24.354,24.354V297.598z" /> </group> </vector> 

We created a parent element that contains information about the size of the image, inside which we placed an element with six elements that were slightly modified compared to the svg file. In this article, the “name” field serves only to make it easier to understand where the element is. In the following articles they will be used. The resulting file still boasts a modest size of 2412 bytes.

Now we can use this file like any other drawable:


res / layout / activity_vector_drawables.xml
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".VectorDrawablesActivity"> <ImageView android:id="@+id/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/android" android:contentDescription="@null" /> </RelativeLayout> 

... and if we run this, we will see a nice drawing:


image


So now we can significantly reduce the size of the APK, if we use VectorDrawable, where appropriate. It also allows you to simplify the development of the application, especially if you need to add support for new screen densities. However, this is not all that VectorDrawable can do. In the next part of the article, we will look at how to animate it.


Sources for this part of the article can be found here .


')

Source: https://habr.com/ru/post/301578/


All Articles