VectorDrawable — часть вторая

Original author: Mark Allison
  • Translation
  • Tutorial

В предыдущей статье мы рассмотрели, как преобразовать существующий svg-файл в VectorDrawable, который позволяет заменить много растровых изображений на одно, меньшее по размеру и более простое в обслуживании. Однако, это не все полезности, которые можно извлечь из VectorDrawable. Его можно анимировать. Это мы и рассмотрим в данной статье, заставив логотип андроид пожимать плечами.


Анимация, которую мы задумали — это простое движение по оси Y. Мы хотим перемещать голову и руки, но оставить неподвижным тело. На первый взгляд все это выглядит довольно сложно, потому что это все элементы одного Drawable. Но в Lollipop, вместе с VectorDravable был введен компонент, который очень сильно упрощает нам задачу. А именно — AnimatedVectorDrawable. В предыдущей статье мы дали каждому элементу path имя, и теперь можем применить анимацию для различный path в пределах VectorDrawable. На практике это оказалось немного затруднительно, потому что path не имеет таких атрибутов, как translateX и translateY, которые мы можем контролировать аниматором. Элемент group имеет необходимые нам атрибуты, поэтому мы обернули голову и руки в grope:


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">
        <group android:name="head_eyes">
            <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" />
        </group>
        <group android:name="arms">
            <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="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>
        <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" />
    </group>
</vector>

Теперь мы можем написать drawable с animated-vector, чтобы применить анимацию к нужным группам, нашего изображения:


res/drawable/animated_android.xml
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/android">

    <target
        android:animation="@animator/shrug"
        android:name="head_eyes" />

    <target
        android:animation="@animator/shrug"
        android:name="arms" />
</animated-vector>

Я знаю, что можно было объединить голову и руки в одну группу, но сознательно разделил на две, чтобы показать, как несколько групп можно анимировать при помощи одного animated-vector.


Родительский элемент "animated-vector" определяет VectorDrawable, который мы будем анимировать. А внутренние элементы target определяют тип анимации и группу, к которой будет применена данная анимация.


Существуют разные параметры, которые можно анимировать у различных элементов, таких как vector, group, clip-path и path. Поэтому нужно посмотреть VectorDravable JavaDocs, чтобы узнать какие элементы использовать для конкретной анимации. Например, изменять параметр tint, необходимо у элемента vector, тогда как изменение цвета заливки нужно делать у параметра path.


Напишем простую анимацию изменения положения по Y для пожимания плечами нашего андроида:


res/animator/shrug.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:propertyName="translateY"
        android:valueType="floatType"
        android:valueFrom="0"
        android:valueTo="-10"
        android:repeatMode="reverse"
        android:repeatCount="infinite"
        android:duration="250" />
</set>

Для того чтобы запустить эту анимацию нам нужно сделать пару вещей. Для начала мы должны изменить Drawable, что мы установили на ImageView в нашем layout:


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/animated_android"
        android:contentDescription="@null" />

</RelativeLayout>

Если мы запустим приложение, то увидим статичное изображение, потому что анимацию необходимо запустить из activity:


VectorDrawablesActivity.java
public class VectorDrawablesActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_vector_drawables);
        ImageView androidImageView = (ImageView) findViewById(R.id.android);
        Drawable drawable = androidImageView.getDrawable();
        if (drawable instanceof Animatable) {
            ((Animatable) drawable).start();
        }
    }
}

Если запустить приложение теперь, то мы увидим, что анимация работает и применяется только к нужным нам частям изображения:



В следующей статье мы глубже изучим и рассмотрим некоторые действительно крутые методы анимации, которые можно сделать при помощи AnimatedVectorDrawable.


Исходный код для этой статьи доступен здесь.

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 0

Only users with full accounts can post comments. Log in, please.