Статьи

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

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


Вы можете создать новое приложение или добавить анимацию в существующее приложение. Вам понадобится класс Activity и макет для него. В демонстрационном коде приложение называется «AnimatedApp» с «AnimatedActivity» в качестве основного класса Activity и «Activity_animated» для файла XML макета. Мы будем редактировать Activity Java и макет XML, а также создавать различные дополнительные файлы ресурсов.


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

Внутри вашего нового XML-файла drawables введите следующий код для представления неба:

01
02
03
04
05
06
07
08
09
10
<shape xmlns:android=»http://schemas.android.com/apk/res/android»
    android:dither=»true»
    android:shape=»rectangle» >
 
    <gradient
        android:angle=»90″
        android:endColor=»#ff000033″
        android:startColor=»#ff0000ff» />
 
</shape>

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

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


Затем создайте еще один нарисованный файл, на этот раз назвав его «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=»150dp»
        android:width=»150dp» />
 
</shape>

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


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

01
02
03
04
05
06
07
08
09
10
<shape xmlns:android=»http://schemas.android.com/apk/res/android»
    android:dither=»true»
    android:shape=»rectangle» >
 
    <gradient
        android:angle=»90″
        android:endColor=»#ff003300″
        android:startColor=»#ff009900″ />
 
</shape>

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


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

1
2
3
4
5
<string name=»sun»>Sun</string>
<string name=»grass»>Grass</string>
<string name=»sky»>Sky</string>
<string name=»clock»>Clock</string>
<string name=»hour»>Hour Hand</string>

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

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

1
2
3
4
5
6
7
<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»
    tools:context=».AnimatedActivity» >
 
</RelativeLayout>

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

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

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

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

1
2
3
4
5
6
7
8
<ImageView
    android:id=»@+id/sun»
    android:layout_width=»wrap_content»
    android:layout_height=»wrap_content»
    android:layout_centerHorizontal=»true»
    android:contentDescription=»@string/sun»
    android:scaleType=»fitCenter»
    android:src=»@drawable/sun» />

На этот раз мы обертываем содержимое, потому что мы явно определили размер в рисуемой форме. Использование масштабного типа позволяет нам настроить Android для подгонки фигуры к доступному размеру экрана, если он слишком большой. Мы центрируем фигуру солнца горизонтально в макете.

Теперь добавьте траву:

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

Форма травы заполнит этот вид, который определен как часть экрана высотой 150dp и выровнен по дну его контейнера.

Это первоначальный вид макета. Мы добавим еще пару элементов и изменим исходное положение солнца.

Внешний вид Первоначальный Внешний вид

Вот как будет выглядеть действие, когда анимация начинается на реальном устройстве — мы добавим часы позже, и начальная позиция солнца (внизу, за травой) будет определена как часть кода анимации:

Анимация Первоначальный Внешний вид

Теперь мы можем определить анимацию, с помощью которой фигура солнца поднимется вверх по экрану «Активность». Создайте новую папку в каталоге ресурсов вашего приложения, выбрав «res» и выбрав «Файл», «Новый», «Папка» (или щелкнув правой кнопкой мыши и выбрав «Новый», «Папка»). Назовите папку «anim» — здесь будут храниться наши определения анимации.

Создайте новый файл в папке «anim» и назовите его «sun_rise.xml». В новом файле введите следующую схему:

1
2
3
4
5
6
<set xmlns:android=»http://schemas.android.com/apk/res/android»
    android:shareInterpolator=»false»
    android:duration=»5000″
    android:fillAfter=»true»
    android:interpolator=»@android:anim/accelerate_decelerate_interpolator» >
</set>

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

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

1
2
3
4
5
6
7
8
<scale
    android:fromXScale=»1.0″
    android:toXScale=»1.5″
    android:fromYScale=»1.0″
    android:toYScale=»1.5″
    android:pivotX=»50%»
    android:pivotY=»50%»
    />

Форма начнется с нормального размера и закончится в 1,5 раза больше, чем на обеих осях. Центральная точка останется прежней, поскольку мы применяем ее как опорную точку для шкалы.

Затем добавьте элемент перевода, чтобы переместить солнце вверх по экрану:

1
2
3
4
<translate
    android:fromYDelta=»80%p»
    android:toYDelta=»10%p»
    />

Перевод чисто вертикальный, поэтому мы определяем только начальную и конечную точки Y. Мы определяем точки перевода относительно родительского элемента, используя суффикс «p». Солнце будет начинаться на 80% вдоль оси Y его родительского элемента и заканчиваться на 10% вдоль него, перемещая его вверх по мере прохождения анимации.

Давайте также увеличим непрозрачность солнца по мере его роста, добавив альфа-элемент:

1
2
3
4
<alpha
    android:fromAlpha=»0.3″
    android:toAlpha=»1.0″
    />

Солнце будет в основном прозрачным и закончится с полной непрозрачностью.

Вот как анимация будет выглядеть на полпути:

Анимация на полпути

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

1
2
3
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;

Внутри вашего метода onCreate , после существующего кода, получите ссылку на Sun Image View:

1
2
//get the sun View
ImageView sun = (ImageView) findViewById(R.id.sun);

Теперь загрузите анимацию восхода, которую вы определили:

1
2
//get the sunrise animation
Animation sunRise = AnimationUtils.loadAnimation(this, R.anim.sun_rise);

Мы ссылаемся на анимацию, используя ее идентификатор ресурса. Теперь начните анимацию, применяя ее к солнцу.

1
2
//apply the animation to the View
sun.startAnimation(sunRise);

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

Вот анимация немного дальше (включая часы, которые мы добавим далее):

Анимация на полпути

Чтобы закрепить то, что мы узнали, давайте снова пройдем процесс, чтобы добавить в приложение простую анимацию часов. Начните с создания нового нарисованного файла с именем «clock.xml». На этот раз мы будем использовать Layer List, чтобы включить более одной фигуры:

1
2
3
<layer-list xmlns:android=»http://schemas.android.com/apk/res/android» >
 
</layer-list>

Внутри Layer List добавьте первый элемент, который имеет форму круга:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
<item>
    <shape
        xmlns:android=»http://schemas.android.com/apk/res/android»
        android:dither=»true»
        android:shape=»oval» >
        <gradient
            android:endColor=»#ffffffff»
            android:gradientRadius=»100″
            android:startColor=»#66ffffff»
            android:type=»radial»
            android:useLevel=»false» />
 
        <size
            android:height=»100dp»
            android:width=»100dp» />
 
        <stroke
            android:width=»2dp»
            android:color=»#99000000″ />
    </shape>
</item>

Форма овальная, с радиальным градиентом, явным размером и штрихом. Затем, все еще в списке слоев, добавьте форму стрелки часов:

01
02
03
04
05
06
07
08
09
10
11
<item
    android:bottom=»44dp»
    android:left=»48dp»
    android:right=»48dp»
        android:top=»5dp»>
    <shape
        xmlns:android=»http://schemas.android.com/apk/res/android»
        android:shape=»rectangle» >
        <solid android:color=»#99000000″ />
    </shape>
</item>

На этот раз мы определяем форму как прямоугольник, свойства которого зависят от формы круга, над которым он появится. Мы используем размеры формы круга, чтобы прямоугольник выглядел как минутная стрелка на круглом циферблате.

Теперь создайте новый файл в папке «anim», назвав его «clock_turn.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:duration=»5000″
    android:fillAfter=»true»
    android:interpolator=»@android:anim/linear_interpolator»
    android:shareInterpolator=»false» >
 
    <rotate
        android:fromDegrees=»0″
        android:pivotX=»50%»
        android:pivotY=»50%»
        android:toDegrees=»720″ />
 
</set>

Эта анимация будет проходить в течение того же периода, что и анимация восхода солнца, поскольку мы даем ей ту же продолжительность. На этот раз интерполятор линейный, поэтому изменение будет применяться с постоянной скоростью. На этот раз анимация представляет собой вращение, начинающееся с начальной позиции фигуры и вращающееся в два полных круга (720 градусов). Центральная точка круга останется прежней из-за атрибутов поворота. Хотя вся форма круга будет вращаться, пользователю будет казаться, что стрелка вращается вокруг циферблата.

Добавьте часы в XML-файл макета после существующих представлений изображений:

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

Он появится в правом нижнем углу.

В вашем классе Activity после существующего кода анимации восхода получите ссылку на часы:

1
2
//get the clock View
ImageView clock = (ImageView) findViewById(R.id.clock);

Далее загружаем анимацию:

1
2
//get the clock turn animation
Animation clockTurn = AnimationUtils.loadAnimation(this, R.anim.clock_turn);

Теперь примените это к форме часов:

1
2
//apply the animation to the View
clock.startAnimation(clockTurn);

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

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<layer-list xmlns:android=»http://schemas.android.com/apk/res/android» >
 
    <item>
        <shape
            xmlns:android=»http://schemas.android.com/apk/res/android»
            android:dither=»true»
            android:shape=»oval» >
            <solid android:color=»#00000000″ />
 
            <size
                android:height=»100dp»
                android:width=»100dp» />
        </shape>
    </item>
    <item
        android:bottom=»44dp»
        android:left=»48dp»
        android:right=»48dp»
        android:top=»15dp»>
        <shape
            xmlns:android=»http://schemas.android.com/apk/res/android»
            android:shape=»rectangle» >
            <solid android:color=»#99000000″ />
        </shape>
    </item>
 
</layer-list>

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

Добавьте новую форму в XML макета после существующих элементов, чтобы она появилась сверху:

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

Он находится точно в том же положении, что и предыдущая фигура.

Теперь создайте новый ресурс анимации в папке «anim», назвав его «hour_turn.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:duration=»5000″
    android:fillAfter=»true»
    android:interpolator=»@android:anim/linear_interpolator»
    android:shareInterpolator=»false» >
 
    <rotate
        android:fromDegrees=»180″
        android:pivotX=»50%»
        android:pivotY=»50%»
        android:toDegrees=»240″ />
 
</set>

На этот раз форма начнется уже повернутой на 180 градусов, так что это будет 6 часов. В течение той же продолжительности, что и в других анимациях, он будет двигаться на 60 градусов, так что в конце он окажется на 8 часов, отражая два полных поворота минутной стрелки на 360 градусов.

Откройте Java Activity и примените новую анимацию:

1
2
3
4
5
6
//get the hour hand View
ImageView hour = (ImageView) findViewById(R.id.hour);
//get the hour turn animation
Animation hourTurn = AnimationUtils.loadAnimation(this, R.anim.hour_turn);
//apply the animation to the View
hour.startAnimation(hourTurn);

Вот анимация в конечной точке:

Конец анимации

На этом наша простая анимация анимации завершена! Мы экспериментировали с набором элементов, которые вы можете использовать в анимации анимации для элемента View: translate, alpha, scale и rotate. В качестве альтернативы вы можете использовать анимацию свойств для изменения определенных свойств элемента с течением времени, таких как его цвет или рамочная анимация, в которой вы отображаете последовательность изображений. Элементы анимации, которые мы использовали выше, имеют множество дополнительных атрибутов, которые вы можете попробовать, поэтому поэкспериментируйте с вашими приложениями, чтобы увидеть, что возможно.