В этой стате хотел бы всем рассказать и показать на практике, как можно делать анимацию в Android приложении при помощи AnimatedVectorDrawableCompat, например свои кастомные кнопки, ImageView, FloatingActionButton.
На сегодняшний день информации по этому поводу в сети не так много, точней ее совсем — нет. Все, что мне удалось найти — это недавние представленные новшества Google, а именно:
Статья из Android Developer Blog
Видео с Google I/O 2016
Android Reference
Этого по сути мало, чтобы понять, как применить на практике AnimatedVectorDrawableCompat.
Теперь непосредственно перейдем к применению.
На первом этапе нам нужно избавиться от того, чтоб фреймворк превращал иконку в .png. С версии 23.3.0 можно использовать .xml и для это нужно в Gradle app level добавить следующий flag:
И в зависимость подключить последнюю версию AppComapt:
Далее, в примере я буду использовать квадрат (синий), который будет немного накрывать своими углами круг (красный).
На выходе мы должны задействовать 2 объекта и заставить их непрерывно двигаться соответственно по оси X (квадрат) и Y (круг).
Шаги:
1)
Создаем Drawable Resource File, называем файл — icon.xml и кладем в папку drawable:
2)
Для хранения анимации в своем проекте мы создаем папку animator — res/animator
В нее мы положим два объекта и назовем их соответственно:
a) circle.xml:
b) square.xml
Здесь же мы и указали, что объекты будут двигать по оси X и Y, откуда будут начинать движение, а также бесконечность движений.
Если у вас больше именованных групп, которые нужно анимировать — то вот в этой директории их и нужно создавать, соответсвенно и больше групп будут в основном файле — icon.xml
3)
Теперь создаем непосредственно анимированный файл, на который будем ссылаться в layout или в коде — res/drawable/anim_icon:
Примечание: Android Studio подчёркивает красным animated-vector (если мин.версия проекта меньше 21), но если вы подключили flag, как указанно в начале — все заработает.
4)
Теперь мы можем обращаться к анимированным векторам в xml. Это может быть — ImageView, ImageButton, FloatingActinonButton:
5)
Обращаемся из кода к векторам. Здесь я также повесил OnClickListener и сохранил состояние при перевороте:
Примечание: не забудьте подтянуть зависимость:
Результат проделанной работы:
P.S
Недавно появилась возможность объединить файлы 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:
<?xml version="1.0" encoding="utf-8"?>
<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:
<?xml version="1.0" encoding="utf-8"?>
<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
<?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="5"
android:repeatMode="reverse"
android:repeatCount="infinite"
android:duration="250" />
</set>
Здесь же мы и указали, что объекты будут двигать по оси X и Y, откуда будут начинать движение, а также бесконечность движений.
Если у вас больше именованных групп, которые нужно анимировать — то вот в этой директории их и нужно создавать, соответсвенно и больше групп будут в основном файле — icon.xml
3)
Теперь создаем непосредственно анимированный файл, на который будем ссылаться в layout или в коде — res/drawable/anim_icon:
<?xml version="1.0" encoding="utf-8"?>
<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;
@Override
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() {
@Override
public void onClick(View v) {
if (avd.isRunning()) {
avd.stop();
mIsAnim = false;
}
avd.start();
mIsAnim = true;
}
});
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(STATE_ANIM, mIsAnim);
}
}
Примечание: не забудьте подтянуть зависимость:
import android.support.graphics.drawable.AnimatedVectorDrawableCompat;
Результат проделанной работы:
P.S
Недавно появилась возможность объединить файлы my_vector.xml и anim_vector в одном anim_vector (теперь отдельный файл res/drawable/my_vector.xml не нужен), а также добавить сюда и файлы-аниматоры (objectAnimator) таким образом получится один файл на всю анимацию.
Представили это Google на I/O, но к сожалению — не работает. На видео с 14 минуты говориться об этом.
Поделиться с друзьями
Beanut
что там с minSDK?
StanZakharov
От 11 API эта тема функциклирует, да забыл об этом упомянуть в статье, а это одна из самых главных причин с ней работать.
Beanut
PathMorphing тоже работает? Потому что когда я последний раз смотрел, там работали только какие то базовые анимации.
StanZakharov
PathMorphing не работает с апкомпатом