Index

Android apps - Animation

See AndroidStudio's tutorial on animations and Animation Resources.

I am gradually figuring out how this works...

Create 'anim' directory
Set up defintion of animation
Use animation
Rotate
Stretch x axis
Stretch y axis
Stopping things happening during an animation
One animation following another
Using animation within a grid

Create 'anim' directory

This type of animation is View Animation, which is applied to a view. XML code needs to be put into a directory, app/res/anim, which you need to create. Right click on app/res, then 'New', then 'Directory' (not Android resource directory!) and create anim.


Set up defintion of animation

Right click on this newly created app/res/anim to create a new file called 'hyperspace_jump.xml'. Put the following code:

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <set android:shareInterpolator="false"> <scale android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromXScale="1.0" android:toXScale="1.4" android:fromYScale="1.0" android:toYScale="0.6" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:duration="700" /> <set android:interpolator="@android:anim/decelerate_interpolator"> <scale android:fromXScale="1.4" android:toXScale="0.0" android:fromYScale="0.6" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:startOffset="700" android:duration="400" android:fillBefore="false" /> <rotate android:fromDegrees="0" android:toDegrees="-45" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:startOffset="700" android:duration="400" /> </set> </set> </set>

This is the example from AndroisStudio that I copied. It is used to stretch, then simultaneously spin and rotate a View object. Simpler examples follow!


Use animation

I am going to need an images file for the animation. Copy it into into app/res/drawable (see Pictures). In this example, I've called it 'star.gif'

I also need an Image View in app/res/layout/.activity_main to actually use this picture. This follows normal format rules. Nothing about it being an animation in here!

<ImageView android:id="@+id/starImage" android:src="@drawable/star" android:onClick="redoPic" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/descPic" android:layout_centerHorizontal="true" />

In app/java/com.(the project name)/MainActivity, in the onCreate method, code this (or equivalent):

public void redoPic(View view) { ImageView moveStar = (ImageView) findViewById(R.id.starImage); Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump); moveStar.startAnimation(hyperspaceJumpAnimation); }

"redoPic" - this method is defined in the 'onClick' in the ImageView in app/res/layout/.activity_main
"moveStar" - internal name I've given for this "findViewById" - used in the third line as well.
"starImage" - "id" of my image in app/res/layout/activity_main.xml.
"hyperspaceJumpAnimation" - internal name I've given for this - used in the third line as well.
"hyperspace_jump" - name of my animation in app/res/anim.

The rest is Java stuff - just copy it.

Click on the picture to make it work. Just don't ask why a star goes into a hyperspace jump!


Rotate

This is the first of a set of simpler examples. I am just giving the animation file. You action them as above. As each one is a different animation, perhaps they could be actioned via buttons rather than clicking on the picture. As you can see above, you specify picture, then animation, in the Java code.

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <rotate android:fromDegrees="0" android:toDegrees="360" android:pivotX="50%" android:pivotY="50%" android:startOffset="100" android:duration="1000" /> </set>

Set it up the same way as 'hyperspace_jump.xml' - call it 'rotate.xml', perhaps. (When giving the name, you don't need the '.xml'.
'rotate' says you want to rotate it.
'android:fromDegrees' says where you are going to start from. '0' is normal position. Specify anything else and it will jump there at the start of the animation.
'android:toDegrees' is how much you are going to rotate it. '360' is a full circle.
'android:pivotX' and 'android:pivotY' tell you where you are pivotting round. Make them both 50% to pivot round the middle. If you leave them our, they pivot round one corner which is fun, but not what you wanted, perhaps.
'android:startOffset' is a pause before you start. You can omit this.
'android:duration' - how long. I'm guessing that 1000 is a second.


Strech x axis

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <scale android:fromXScale="0.5" android:toXScale="1.4" android:fromYScale="1.0" android:toYScale="1.0" android:pivotX="50%" android:pivotY="50%" android:duration="700" /> </set>

Again, this needs to be a new file, as above.
'scale' says you want to stretch (or shrink) it.
'android:fromXScale' says where you are going to start from. '1.0' is normal position. This specifies '0.5' so that's where the animation with start - with the x axis being half the size.
'android:toXScale' is how much you are going to strech it.
You also need 'android:fromYScale' and 'android:toYScale' or it blanks out! Make them 1.0 if the Y axis remains uncg=hanged.
'android:pivotX' and 'android:pivotY' tell you where you are pivotting round. Make them both 50% to stretch or shrink round the middle. If you leave them out, they go right (or down for Y).
'android:duration' - as above


Strech y axis

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <scale android:fromXScale="1.0" android:toXScale="1.0" android:fromYScale="1.0" android:toYScale="1.4" android:duration="700" /> </set>

Again, this needs to be a new file, as above. This code is very similar to above. It's left out the pivot, so the whole thing streches downwards. And 'android:fromYScale' starts from 1.0, so it doesn't shrink first.

You can combine x and y stretch/shrink if you wish.


Stopping things happening during an animation

While animations are running, the app carries on processing. This can lead to muddle. To stop this, define as a gobal variable:

public static int ok = 1;

Set it to 1 in the onCreate method as well.

In the animation start, set up the Listener like this. It must be done before actually starting the animation.

public void doRotate(View view) { ImageView starImage = (ImageView) findViewById(R.id.starPic); Animation anim = AnimationUtils.loadAnimation(this, R.anim.rotate); anim.setAnimationListener(new Animation.AnimationListener() { public void onAnimationStart(Animation animation) {ok=0;} public void onAnimationRepeat(Animation animation) {} public void onAnimationEnd(Animation animation) {ok=1;} }); starImage.startAnimation(anim); }

Then for other piece of code, such as clicking on a button, for example, put at the start of the button method:

if (ok==0) {return;}

One animation following another

It may seem that you can make one animation follow another by defining them separately, and starting one, then the other. This doesn't work. Both will run at the same time (so you get the second happening). You might think that you could use the technique of switches (see above) or even put the second animation start inside the onAnimationEnd of the first. That will work technically. But when the first animation ends, the picture (or whatever) reverts back to its initial state. If the second animation assumes it has some other position, then you get a jerky join. It is better to have it as a single animation.

<set xmlns:android="http://schemas.android.com/apk/res/android"> <rotate android:fromDegrees="0" android:toDegrees="180" android:pivotX="50%" android:pivotY="50%" android:duration="1000" /> <scale android:startOffset="2000" android:fromXScale="1.0" android:toXScale="0.0" android:fromYScale="1.0" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="1000" /> </set> "android:startOffset" is IMPORTANT! If you don't have it, both animations will run at the same time (sigh). So you put this term in to start the second animation that time after the start of the first one. Obviously you could make them happen next to each other. This example gives a gap of "1000" (a second?) between them.



© Jo Edkins 2016 - Index to Android app index