В этой стате хотел бы всем рассказать и показать на практике, как можно делать анимацию в Android приложении при помощи AnimatedVectorDrawableCompat, например свои кастомные кнопки, ImageView, FloatingActionButton.
На сегодняшний день информации по этому поводу в сети не так много, точней ее совсем — нет. Все, что мне удалось найти — это недавние представленные новшества Google, а именно:
Статья из Android Developer Blog
Видео с Google I/O 2016
Android Reference
Этого по сути мало, чтобы понять, как применить на практике AnimatedVectorDrawableCompat.
Теперь непосредственно перейдем к применению.
На первом этапе нам нужно избавиться от того, чтоб фреймворк превращал иконку в .png. С версии 23.3.0 можно использовать .xml и для это нужно в Gradle app level добавить следующий flag:
android { ... defaultConfig { ... vectorDrawables.useSupportLibrary = true } }
И в зависимость подключить последнюю версию AppComapt:
dependencies { ... compile 'com.android.support:appcompat-v7:23.4.0' }
Далее, в примере я буду использовать квадрат (синий), который будет немного накрывать своими углами круг (красный).
На выходе мы должны задействовать 2 объекта и заставить их непрерывно двигаться соответственно по оси X (квадрат) и Y (круг).
Шаги:
1)
Создаем Drawable Resource File, называем файл — icon.xml и кладем в папку drawable:
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="120dp" android:height="120dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> <group android:name="circle" android:scaleX=".7" android:scaleY=".7" android:pivotX="12" android:pivotY="12"> <path android:fillColor="#ff0000 " android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2z"/> </group> <group android:name="square" android:scaleX="1" android:scaleY="1" android:pivotX="12" android:pivotY="12"> <path android:fillColor="#FF0000ff" android:pathData="M6,6h12v12H6z"/> </group> </vector>
2)
Для хранения анимации в своем проекте мы создаем папку animator — res/animator
В нее мы положим два объекта и назовем их соответственно:
a) circle.xml:
<set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:propertyName="translateX" android:valueType="floatType" android:valueFrom="0" android:valueTo="5" android:repeatMode="reverse" android:repeatCount="infinite" android:duration="250" /> </set>
b) square.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:propertyName="translateY" android:valueType="floatType" android:valueFrom="0" android:valueTo="5" android:repeatMode="reverse" android:repeatCount="infinite" android:duration="250" /> </set>
Здесь же мы и указали, что объекты будут двигать по оси X и Y, откуда будут начинать движение, а также бесконечность движений.
Если у вас больше именованных групп, которые нужно анимировать — то вот в этой директории их и нужно создавать, соответсвенно и больше групп будут в основном файле — icon.xml
3)
Теперь создаем непосредственно анимированный файл, на который будем ссылаться в layout или в коде — res/drawable/anim_icon:
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/icon"> <target android:name="square" android:animation="@animator/square" /> <target android:name="circle" android:animation="@animator/circle" /> </animated-vector>
Примечание: Android Studio подчёркивает красным animated-vector (если мин.версия проекта меньше 21), но если вы подключили flag, как указанно в начале — все заработает.
4)
Теперь мы можем обращаться к анимированным векторам в xml. Это может быть — ImageView, ImageButton, FloatingActinonButton:
<LinearLayout ... xmlns:app="http://schemas.android.com/apk/res-auto"/> <ImageView app:srcCompat="@drawable/anim_icon" ... /> </LinearLayout>
5)
Обращаемся из кода к векторам. Здесь я также повесил OnClickListener и сохранил состояние при перевороте:
static final String STATE_ANIM = "isAnim"; boolean mIsAnim; AnimatedVectorDrawableCompat avd; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ImageView imageView = (ImageView) findViewById(R.id.imageView); if (imageView != null) { Drawable drawable = imageView.getDrawable(); avd = (AnimatedVectorDrawableCompat) drawable; if (savedInstanceState != null) { mIsAnim = savedInstanceState.getBoolean(STATE_ANIM); if (mIsAnim) { avd.start(); } } imageView.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if (avd.isRunning()) { avd.stop(); mIsAnim = false; } avd.start(); mIsAnim = true; } }); } } public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(STATE_ANIM, mIsAnim); } }
Примечание: не забудьте подтянуть зависимость:
import android.support.graphics.drawable.AnimatedVectorDrawableCompat;
Результат проделанной работы:
Недавно появилась возможность объединить файлы my_vector.xml и anim_vector в одном anim_vector (теперь отдельный файл res/drawable/my_vector.xml не нужен), а также добавить сюда и файлы-аниматоры (objectAnimator) таким образом получится один файл на всю анимацию.
Представили это Google на I/O, но к сожалению — не работает. На видео с 14 минуты говориться об этом.
На сегодняшний день информации по этому поводу в сети не так много, точней ее совсем — нет. Все, что мне удалось найти — это недавние представленные новшества Google, а именно:
Статья из Android Developer Blog
Видео с Google I/O 2016
Android Reference
Этого по сути мало, чтобы понять, как применить на практике AnimatedVectorDrawableCompat.
Теперь непосредственно перейдем к применению.
На первом этапе нам нужно избавиться от того, чтоб фреймворк превращал иконку в .png. С версии 23.3.0 можно использовать .xml и для это нужно в Gradle app level добавить следующий flag:
android { ... defaultConfig { ... vectorDrawables.useSupportLibrary = true } }
И в зависимость подключить последнюю версию AppComapt:
dependencies { ... compile 'com.android.support:appcompat-v7:23.4.0' }
Далее, в примере я буду использовать квадрат (синий), который будет немного накрывать своими углами круг (красный).
На выходе мы должны задействовать 2 объекта и заставить их непрерывно двигаться соответственно по оси X (квадрат) и Y (круг).
Шаги:
1)
Создаем Drawable Resource File, называем файл — icon.xml и кладем в папку drawable:
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="120dp" android:height="120dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> <group android:name="circle" android:scaleX=".7" android:scaleY=".7" android:pivotX="12" android:pivotY="12"> <path android:fillColor="#ff0000 " android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2z"/> </group> <group android:name="square" android:scaleX="1" android:scaleY="1" android:pivotX="12" android:pivotY="12"> <path android:fillColor="#FF0000ff" android:pathData="M6,6h12v12H6z"/> </group> </vector>
2)
Для хранения анимации в своем проекте мы создаем папку animator — res/animator
В нее мы положим два объекта и назовем их соответственно:
a) circle.xml:
<set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:propertyName="translateX" android:valueType="floatType" android:valueFrom="0" android:valueTo="5" android:repeatMode="reverse" android:repeatCount="infinite" android:duration="250" /> </set>
b) square.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:propertyName="translateY" android:valueType="floatType" android:valueFrom="0" android:valueTo="5" android:repeatMode="reverse" android:repeatCount="infinite" android:duration="250" /> </set>
Здесь же мы и указали, что объекты будут двигать по оси X и Y, откуда будут начинать движение, а также бесконечность движений.
Если у вас больше именованных групп, которые нужно анимировать — то вот в этой директории их и нужно создавать, соответсвенно и больше групп будут в основном файле — icon.xml
3)
Теперь создаем непосредственно анимированный файл, на который будем ссылаться в layout или в коде — res/drawable/anim_icon:
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/icon"> <target android:name="square" android:animation="@animator/square" /> <target android:name="circle" android:animation="@animator/circle" /> </animated-vector>
Примечание: Android Studio подчёркивает красным animated-vector (если мин.версия проекта меньше 21), но если вы подключили flag, как указанно в начале — все заработает.
4)
Теперь мы можем обращаться к анимированным векторам в xml. Это может быть — ImageView, ImageButton, FloatingActinonButton:
<LinearLayout ... xmlns:app="http://schemas.android.com/apk/res-auto"/> <ImageView app:srcCompat="@drawable/anim_icon" ... /> </LinearLayout>
5)
Обращаемся из кода к векторам. Здесь я также повесил OnClickListener и сохранил состояние при перевороте:
static final String STATE_ANIM = "isAnim"; boolean mIsAnim; AnimatedVectorDrawableCompat avd; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ImageView imageView = (ImageView) findViewById(R.id.imageView); if (imageView != null) { Drawable drawable = imageView.getDrawable(); avd = (AnimatedVectorDrawableCompat) drawable; if (savedInstanceState != null) { mIsAnim = savedInstanceState.getBoolean(STATE_ANIM); if (mIsAnim) { avd.start(); } } imageView.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if (avd.isRunning()) { avd.stop(); mIsAnim = false; } avd.start(); mIsAnim = true; } }); } } public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(STATE_ANIM, mIsAnim); } }
Примечание: не забудьте подтянуть зависимость:
import android.support.graphics.drawable.AnimatedVectorDrawableCompat;
Результат проделанной работы:
Недавно появилась возможность объединить файлы my_vector.xml и anim_vector в одном anim_vector (теперь отдельный файл res/drawable/my_vector.xml не нужен), а также добавить сюда и файлы-аниматоры (objectAnimator) таким образом получится один файл на всю анимацию.
Представили это Google на I/O, но к сожалению — не работает. На видео с 14 минуты говориться об этом.
Комментарии
Отправить комментарий