Ранее в этой серии статей мы рассмотрели реализацию VectorDrawable, изпользуя данные под тегом path в SVG. А после применили несколько простых анимаций к отдельным элементам path.

Romain Guy написал приложение, которое рисует маршруты. Он использовал SVG path, чтобы определить маршрут, а затем по этому маршруту «рисовал» линию путем регулирования параметра dash.

Так как VectorDrawable поддерживает данные SVG из тега path, можем ли мы использовать ту же технику? Конечно можем. Но, на сам деле, нам это не нужно. Мы можем достичь того же эффекта, манипулируя некоторыми атрибутами элемента в нашем VectorDrawable.

Рисование пути не подходит для логотипа Android, который мы использовали в предыдущих статьях, так как он состоит из закрашенных областей, а не линий. Так что давайте для начала определим простой видимый path VectorDrawable. Наша фигура имеет форму звезды, которую мы получили основываясь на SVG-файле. Это относительно простая геометрическая фигура, которая имеет достаточную сумму длин сторон, чтобы прекрасно проиллюстрировать эффект, который мы пытаемся достичь в этой статье. Конечно, вы можете использовать линии границ американских штатов, как Romain.

res/drawable/star.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:viewportHeight="500"
    android:viewportWidth="500"
    android:width="500px"
    android:height="500px">
    <group android:scaleX="5.0" android:scaleY="5.0">
        <path
            android:name="star"
            android:strokeColor="@color/sa_green"
            android:strokeWidth="2"
            android:pathData="M 50.0,90.0 L 82.9193546357,27.2774101308 L 12.5993502926,35.8158045183 L 59.5726265715,88.837672697 L 76.5249063296,20.0595700732 L 10.2916450361,45.1785327898 L 68.5889268818,85.4182410261 L 68.5889268818,14.5817589739 L 10.2916450361,54.8214672102 L 76.5249063296,79.9404299268 L 59.5726265715,11.162327303 L 12.5993502926,64.1841954817 L 82.9193546357,72.7225898692 L 50.0,10.0 L 17.0806453643,72.7225898692 L 87.4006497074,64.1841954817 L 40.4273734285,11.162327303 L 23.4750936704,79.9404299268 L 89.7083549639,54.8214672102 L 31.4110731182,14.5817589739 L 31.4110731182,85.4182410261 L 89.7083549639,45.1785327898 L 23.4750936704,20.0595700732 L 40.4273734285,88.837672697 L 87.4006497074,35.8158045183 L 17.0806453643,27.2774101308 L 50.0,90.0Z" />
    </group>
</vector>


Все, что мы здесь имеем — это очень простой path, основанный на кубической кривой Безье, которому мы мы дали имя, для удобного обращения к нему из AnimatedVectorDrawable.

Сам AnimatedVectorDrawable также довольно простой. Все, что нам нужно сделать, это применить animator/path к указанному path.

res/drawable/animated_star.xml
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/star">
    
    <target
        android:animation="@animator/path"
        android:name="star" />
 
</animated-vector>


Самое интересное находится внутри аниматора, который представляет из себя простой Object Animator, который анимирует значение атрибута trimPathEnd из элемента в VectorDrawable. Этот атрибут управляет тем, какая часть path будет нарисована. Имеет диапазон от 0 (ничего не рисуется) до 1 (весь path будет нарисован). Получается, что все что нам нужно — это анимировать это атрибут от 0 до 1. Таки образом мы создадим впечатление рисования по нашему path, так же, как Romain в своем примере.

Animator, который делает это, выглядит довольно просто: время анимации установлено 5 секунд, для того, чтобы отчетливо рассмотреть что у нас получилось. Так же установлен линейный интерполятор, потому что мы не хотим, чтобы скорость рисования менялась с течением времени:

res/animator/path.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="trimPathEnd"
    android:valueFrom="0"
    android:valueTo="1"
    android:duration="5000"
    android:valueType="floatType"
    android:interpolator="@android:interpolator/linear">
 
</objectAnimator>


Нам остается только использовать AnimatedVectorDrawable в нашем layout (в примере кода я на самом деле реализовал все в ViewPager, чтобы иметь возможность переключаться между примерами. Это не обязательно).

Мы смогли достичь такого же результата, как Romain, но использовали гораздо меньше кода. На самом деле для данной реализации нам не потребовалось ни строчки java-кода (сверх того, что мы написали раньше, чтобы отобразить и начать анимацию). Так выглядит результат:


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

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

Комментарии (2)


  1. DmitryO
    17.02.2017 14:13
    +1

    Сорри, заминусовал. Просто решил с февраля всем постам про андроид ставить оценку, а то качество контента на хабре падает ниже плинтуса.

    За что минус?

    Вы перевели статью двухгодичной давности, причем предыдущую часть вы же переводили еще год назад. Да за это время все уже успели так эти VectorDrawable обсосать, взять хотя бы того же Марка, что данный пост вообще никакой новизны не несет. Даже немного вредит. Мажорный API уже два раза поменялся, ну право нельзя так, нехорошо это (С).


    1. IIblBko
      17.02.2017 17:57

      Извиняться вовсе не нужно было. Всё по делу. Перевел я именно эту статью, потому что хотел закончить начатое. И четвертую часть в ближайшее время тоже переведу.