Статьи

Android SDK: создание простой анимации свойств

С Android вы можете включать различные типы анимации в свои приложения. В этом уроке мы создадим базовую анимацию свойств, используя классы Android Object Animator и Value Animator. Результат будет простым, но используемые методы будут применяться в более сложных анимационных эффектах. Мы создадим анимацию, в которой руль поворачивается и фоновая сцена перемещается соответственно.

С анимацией свойств у вас есть несколько дополнительных параметров, чем с анимацией просмотра, например, вы можете анимировать элементы пользовательского интерфейса, отличные от представлений, и анимировать больше свойств. Анимация свойств также может иметь более согласованные результаты в некоторых случаях, так как в отличие от анимации View, она изменяет сами объекты UI, а не просто выводит их особым образом. Недостатком этих преимуществ является то, что анимация свойств немного сложнее, но все же доступна для начинающих.


Запустите или откройте проект Android в Eclipse. Вам понадобится пустой Activity и макет для него. Вам также нужно будет выбрать минимальный SDK 11, чтобы использовать методы из этого учебного пособия, поэтому убедитесь, что в манифесте вашего проекта указан соответствующий уровень, как в следующем фрагменте:

1
2
3
4
<uses-sdk
    android:minSdkVersion=»11″
    android:targetSdkVersion=»16″
/>

В учебном и исходном коде приложение называется «PropertyAnimatedApp», действие — «PropertyAnimatedActivity», а макет — «activity_property_animated.xml». Вы можете выбрать свои собственные имена, если будете вносить изменения в приведенный ниже код, если это необходимо.


Мы создадим несколько рисованных файлов в XML для анимации, но также будем использовать пару изображений PNG. Мы будем использовать изображения облаков и рулевого колеса ниже в представлении изображений в макете приложения. Загрузите их из отображенных здесь копий или скопируйте их из исходной папки загрузки. Убедитесь, что вы копируете их в каждую папку drawables в своем приложении — вы можете внести изменения в любой из доступных для рисования файлов, если вы планируете ориентироваться на определенные размеры экрана.

облако
Руль

Теперь давайте определим XML Drawables для остальных элементов анимации. В папке (папках) Drawables вашего приложения создайте первый новый файл, выбрав папку и выбрав «Файл», «Новый», «Файл». Введите «sun.xml» в качестве имени файла. В новом файле введите следующий код, чтобы определить форму солнца:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<shape xmlns:android=»http://schemas.android.com/apk/res/android»
    android:dither=»true»
    android:shape=»oval» >
 
    <gradient
        android:endColor=»#ffff6600″
        android:gradientRadius=»150″
        android:startColor=»#ffffcc00″
        android:type=»radial»
        android:useLevel=»false» />
 
    <size
        android:height=»100dp»
        android:width=»100dp» />
 
</shape>

Рисуемое изображение имеет овальную форму с радиальным градиентным заполнением и заданным размером. Когда вы закончите вводить код для каждого из файлов drawables, сохраните их и скопируйте в каждую папку drawables, которую использует ваше приложение.

Создайте еще один новый файл в ресурсах рисования вашего приложения, на этот раз назвав его «ground.xml». Введите следующую форму для рисования:

1
2
3
4
5
6
7
<shape xmlns:android=»http://schemas.android.com/apk/res/android»
    android:dither=»true»
    android:shape=»rectangle» >
 
    <solid android:color=»#339933″ />
 
</shape>

Земля будет представлена ​​зеленым прямоугольником.

Создайте другой файл drawables, назовите его «window.xml» и введите следующую форму:

01
02
03
04
05
06
07
08
09
10
<shape xmlns:android=»http://schemas.android.com/apk/res/android»
    android:shape=»rectangle» >
 
    <solid android:color=»#00000000″ />
 
    <stroke
        android:width=»40dp»
        android:color=»#cccccc» />
 
</shape>

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

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

Начало анимации

Теперь мы можем включить наши макеты в макет. Мы будем использовать представления изображений, с помощью которых нам необходимо предоставить строку описания содержимого, описывающую изображение в каждом случае. Чтобы подготовиться к этому, откройте файл вашего приложения «res / values ​​/ strings.xml» и добавьте следующие значения:

1
2
3
4
5
<string name=»wheel»>Steering Wheel</string>
<string name=»ground»>The Ground</string>
<string name=»window»>Window Frame</string>
<string name=»sun»>The Sun</string>
<string name=»cloud»>A Cloud</string>

Нам нужна строка для каждого изображения / рисования, которые мы будем использовать.

Теперь откройте файл макета. Замените содержимое следующей относительной компоновкой:

1
2
3
4
5
6
7
8
9
<RelativeLayout xmlns:android=»http://schemas.android.com/apk/res/android»
    xmlns:tools=»http://schemas.android.com/tools»
    android:id=»@+id/car_layout»
    android:layout_width=»match_parent»
    android:layout_height=»match_parent»
    android:background=»#66ccff»
    tools:context=».PropertyAnimatedActivity» >
 
</RelativeLayout>

Измените атрибут контекста, если ваш класс Activity имеет другое имя. Обратите внимание, что мы применяем цвет фона к макету — мы будем анимировать это позже, поэтому мы также включаем атрибут ID для ссылки на макет в Java.

Сначала внутри макета, добавьте Image View для отображения формы солнца, которую мы создали:

1
2
3
4
5
6
7
8
<ImageView
    android:id=»@+id/sun»
    android:layout_width=»wrap_content»
    android:layout_height=»wrap_content»
    android:contentDescription=»@string/sun»
    android:paddingLeft=»100dp»
    android:paddingTop=»45dp»
    android:src=»@drawable/sun» />

Мы включили атрибут ID, чтобы мы могли ссылаться на представление при его анимации. Мы также ссылаемся на одну из созданных нами строк описания содержимого и перечисляем имя рисуемого файла в качестве атрибута источника src . Мы также размещаем вид в макете.

Затем добавьте еще два просмотра изображений для облаков:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<ImageView
    android:id=»@+id/cloud1″
    android:layout_width=»wrap_content»
    android:layout_height=»wrap_content»
    android:contentDescription=»@string/cloud»
    android:paddingLeft=»170dp»
    android:paddingTop=»70dp»
    android:src=»@drawable/cloud» />
 
<ImageView
    android:id=»@+id/cloud2″
    android:layout_width=»wrap_content»
    android:layout_height=»wrap_content»
    android:contentDescription=»@string/cloud»
    android:paddingLeft=»200dp»
    android:paddingTop=»90dp»
    android:src=»@drawable/cloud» />

Эти два идентичны, кроме атрибутов позиционирования и идентификатора.

Затем добавьте землю:

1
2
3
4
5
6
7
8
<ImageView
    android:id=»@+id/ground»
    android:layout_width=»fill_parent»
    android:layout_height=»200dp»
    android:layout_alignParentBottom=»true»
    android:contentDescription=»@string/ground»
    android:padding=»40dp»
    android:src=»@drawable/ground» />

Земля выравнивается по низу родительского просмотра. Обратите внимание, что мы также добавили отступы внизу — для размещения рамки окна мы добавим следующее:

1
2
3
4
5
6
<ImageView
    android:id=»@+id/window»
    android:layout_width=»fill_parent»
    android:layout_height=»fill_parent»
    android:contentDescription=»@string/window»
    android:src=»@drawable/window» />

Форма окна использует обводку шириной 40dp, поэтому мы добавили 40dp отступа для формы основания.

Каждый добавленный просмотр изображений будет отображаться поверх предыдущих элементов с точки зрения z-индекса, поэтому мы добавляем руль последним:

1
2
3
4
5
6
7
8
9
<ImageView
    android:id=»@+id/wheel»
    android:layout_width=»wrap_content»
    android:layout_height=»wrap_content»
    android:layout_alignParentBottom=»true»
    android:layout_centerHorizontal=»true»
    android:contentDescription=»@string/wheel»
    android:padding=»3dp»
    android:src=»@drawable/steering_wheel» />

Макет изначально будет выглядеть следующим образом:

раскладка

Давайте сейчас застрянем в анимации. В папке «res» приложения создайте новую подпапку, выбрав «res» и выбрав «Файл», «Новый», «Папка». Введите «аниматор» в качестве имени папки. Мы добавим два XML-файла в эту папку, определяя анимацию вращения колеса и движения солнца. Начните с создания нового файла в «animator» и назовите его «wheel_spin.xml».

Начните с добавления набора элементов:

1
2
3
4
5
<set xmlns:android=»http://schemas.android.com/apk/res/android»
    android:interpolator=»@android:anim/accelerate_decelerate_interpolator»
    android:ordering=»sequentially» >
 
</set>

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

Внутри набора включите аниматор для поворота колеса:

1
2
3
4
5
6
7
<objectAnimator
    android:duration=»3000″
        android:propertyName=»rotation»
        android:repeatCount=»infinite»
        android:repeatMode=»reverse»
        android:valueTo=»180″
        android:valueType=»floatType» />

Это Object Animator, который сначала определяет продолжительность и свойство для анимации в течение этого периода. Атрибут valueTo указывает на 180 градусов, то есть на сколько колесо будет вращаться в течение продолжительности. Когда анимация завершается, мы устанавливаем ее в обратном направлении и затем непрерывно повторяем.


Теперь давайте обратимся к классу Activity. Сначала добавьте следующие операторы импорта вверху:

1
2
3
4
5
6
7
8
import android.animation.AnimatorInflater;
import android.animation.AnimatorSet;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.graphics.Color;
import android.view.Menu;
import android.widget.ImageView;

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

1
ImageView wheel = (ImageView)findViewById(R.id.wheel);

Теперь создайте Animator Set для загрузки анимации, которую мы определили:

1
AnimatorSet wheelSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.wheel_spin);

Теперь установите элемент View в качестве цели для анимации:

1
wheelSet.setTarget(wheel);

Запустите анимацию:

1
wheelSet.start();

Вы можете запустить приложение, если хотите, чтобы на этом этапе колесо вращалось взад и вперед. Остальные анимации добавят к эффекту, создавая впечатление, что мы движемся в соответствии с управлением, а мир за окном движется вперед и назад одновременно.


Давайте заставим солнце двигаться, чтобы создать впечатление, что мы движемся в результате рулевого управления. Создайте новый файл в папке «animator», на этот раз с именем «sun_swing.xml». Введите следующий код:

01
02
03
04
05
06
07
08
09
10
11
12
13
<set xmlns:android=»http://schemas.android.com/apk/res/android»
    android:interpolator=»@android:anim/accelerate_decelerate_interpolator»
    android:ordering=»sequentially» >
 
    <objectAnimator
        android:duration=»3000″
        android:propertyName=»x»
        android:repeatCount=»infinite»
        android:repeatMode=»reverse»
        android:valueTo=»-400″
        android:valueType=»floatType» />
 
</set>

На этот раз Object Animator анимирует свойство x , перемещая объект влево, когда руль поворачивает нас вправо. Свойства длительности и повторения совпадают с анимацией поворота колеса, поскольку этот эффект должен совпадать с ней.


Вернувшись в метод Activity класса onCreate , примените эту новую анимацию к представлению солнца, используя ту же технику, что и раньше:

1
2
3
4
5
6
7
8
//get the sun view
ImageView sun = (ImageView)findViewById(R.id.sun);
//load the sun movement animation
AnimatorSet sunSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.sun_swing);
//set the view as target
sunSet.setTarget(sun);
//start the animation
sunSet.start();

Запустите приложение еще раз, если вы хотите, чтобы солнце казалось исчезающим из поля зрения и назад.


До сих пор мы реализовали несколько анимаций путем определения ресурсов анимации. Давайте теперь рассмотрим создание анимации в Java из класса Activity. Мы сделаем небо немного темнее, когда солнце исчезнет из поля зрения. Все еще внутри onCreate , создайте экземпляр Value Animator:

1
2
3
ValueAnimator skyAnim = ObjectAnimator.ofInt
    (findViewById(R.id.car_layout), «backgroundColor»,
    Color.rgb(0x66, 0xcc, 0xff), Color.rgb(0x00, 0x66, 0x99));

Мы создаем Value Animator, вызывая метод ofInt класса Object Animator, поскольку мы имеем дело с целочисленными значениями для цветов. Мы передаем идентификатор элемента макета, к которому применен цвет фона, также указав «backgroundColor» в качестве свойства, которое мы хотим анимировать. Наконец, мы указываем цвета для анимации от и до, которые являются более светлыми и темными оттенками синего.

Установите длительность и свойства повтора, чтобы соответствовать существующим анимациям:

1
2
3
skyAnim.setDuration(3000);
skyAnim.setRepeatCount(ValueAnimator.INFINITE);
skyAnim.setRepeatMode(ValueAnimator.REVERSE);

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

1
skyAnim.setEvaluator(new ArgbEvaluator());

Запустите анимацию:

1
skyAnim.start();

Вы можете запустить приложение, чтобы увидеть эффект.


Давайте закончим эту анимацию, переместив два облака. Все еще в onCreate , создайте экземпляр Object Animator для первого облачного представления, указав свойство x и значение для его перемещения:

1
ObjectAnimator cloudAnim = ObjectAnimator.ofFloat(findViewById(R.id.cloud1), «x», -350);

Установите длительность и повторите свойства, как раньше, затем запустите анимацию:

1
2
3
4
cloudAnim.setDuration(3000);
cloudAnim.setRepeatCount(ValueAnimator.INFINITE);
cloudAnim.setRepeatMode(ValueAnimator.REVERSE);
cloudAnim.start();

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

1
2
3
4
5
ObjectAnimator cloudAnim2 = ObjectAnimator.ofFloat(findViewById(R.id.cloud2), «x», -300);
cloudAnim2.setDuration(3000);
cloudAnim2.setRepeatCount(ValueAnimator.INFINITE);
cloudAnim2.setRepeatMode(ValueAnimator.REVERSE);
cloudAnim2.start();

Разница в значении x с анимацией в течение одной и той же продолжительности создаст впечатление, что облака движутся с несколько разными скоростями, причем одно ближе, чем другое.

Анимация Готово

Это приложение завершено — запустите его и поэкспериментируйте с различными свойствами, чтобы увидеть эффект. В этом уроке мы создали простую анимацию свойств. В построенном нами приложении анимация начинается при запуске и работает непрерывно. В ваших собственных приложениях вы, конечно, можете запускать анимацию взаимодействия пользователя с такими элементами, как кнопки. Два других основных типа анимации на Android — это анимация движения и фрейм, оба из которых являются анимациями просмотра. Каждый тип подходит для различных потребностей, в зависимости от ресурсов изображения, с которыми вы работаете, и деталей анимации.