1. Les animations sous Android▲
1-1. Aperçu▲
Android 3.0 a introduit l'API Property Animation qui permet de modifier les propriétés des objets sur un intervalle de temps prédéfini.
L'API permet de définir des valeurs de début et de fin de ces propriétés et d'opérer une modification temporelle sur les attributs. Cette API peut être appliquée à n'importe quel objet Java et non aux seules View.
1-2. Les classes Animator et AnimatorListener▲
La superclasse de l'API d'animation est la classe Animator. Typiquement, la classe ObjectAnimator est utilisée pour modifier les attributs d'un objet.
Vous pouvez également ajouter à votre classe Animator une classe AnimatorListener. Cet écouteur est appelé dans les différentes phases de l'animation. Vous pouvez l'utiliser pour effectuer des actions avant ou après une animation, par exemple ajouter ou supprimer une vue d'un ViewGroup.
1-3. La classe ViewPropertyAnimator▲
La classe ViewPropertyAnimator introduite dans Android 3.1 offre un accès plus simple aux animations typiques effectuées sur des vues.
Dans une vue, la méthode animate() retourne l'objet ViewPropertyAnimator. Celui-ci permet de réaliser des animations simultanées. Il dispose d'une API fluide et permet de définir la durée de l'animation.
L'objectif de ViewPropertyAnimator est de fournir une API très simple pour animations types.
Le code suivant montre un exemple d'utilisation de cette méthode.
//
Utiliser
la
couche
matérielle
myView.animate
(
).translationX
(
400
).withLayer
(
);
Pour optimiser les performances, vous pouvez aussi laisser ViewPropertyAnimator utiliser une disposition matérielle.
//
Utiliser
la
couche
matérielle
myView.animate
(
).translationX
(
400
).withLayer
(
);
Vous pouvez également définir directement un Runnable à exécuter au début et à la fin de l'animation.
//
DébutAction
myView.animate
(
).translationX
(
100
).withStartAction
(
new
Runnable
(
){
public
void
run
(
){
viewer.setTranslationX
(
100
-
myView.getWidth
(
));
//
faites
quelque
chose
}
}
);
//
FinAction
myView.animate
(
).alpha
(
0
).withStartAction
(
new
Runnable
(
){
public
void
run
(
){
//
Remove
the
view
from
the
layout
called
parent
Supprimez
la
vue
de
la
mise
en
page
parent
parent.removeView
(
myView);
}
}
);
La méthode setInterpolator() permet de définir un objet de type TimeInterpolator qui détermine le changement de la valeur au fil du temps. La norme est linéaire. La plate-forme Android spécifie quelques interpolateurs par défaut, comme AccelerateDecelerateInterpolator où le taux de changement commence et se termine lentement, mais accélère au milieu.
Par la méthode setEvaluator(), vous pouvez définir un objet de type TypeEvaluator qui vous permet de créer des animations sur des types quelconques de propriétés, en fournissant des évaluateurs personnalisés pour les types qui ne sont pas automatiquement compris et utilisés par le système d'animation.
1-4. Les animations de mise en page▲
La classe LayoutTransition permet des animations d'adaptation sur un conteneur de mise en page et un changement dans la hiérarchie de la vue de ce conteneur sera animé.
package
com.example.android.layoutanimation;
import
android.animation.LayoutTransition;
import
android.app.Activity;
import
android.os.Bundle;
import
android.view.Menu;
import
android.view.View;
import
android.view.ViewGroup;
import
android.widget.Button;
public
class
MainActivity extends
Activity {
private
ViewGroup viewGroup;
@
Override
public
void
onCreate
(
Bundle savedInstanceState) {
super
.onCreate
(
savedInstanceState);
setContentView
(
R.layout.activity_main);
LayoutTransition l =
new
LayoutTransition
(
);
l.enableTransitionType
(
LayoutTransition.CHANGING);
viewGroup =
(
ViewGroup) findViewById
(
R.id.container);
viewGroup.setLayoutTransition
(
l);
}
public
void
onClick
(
View view) {
viewGroup.addView
(
new
Button
(
this
));
}
@
Override
public
boolean
onCreateOptionsMenu
(
Menu menu) {
getMenuInflater
(
).inflate
(
R.menu.activity_main, menu);
return
true
;
}
}
1-5. Les animations de transition d'activité▲
Les animations peuvent être appliquées aux vues, mais il est également possible de les appliquer aux transitions entre activités.
La classe ActivityOptions permet de définir des animations par défaut ou personnalisées.
public
void
onClick
(
View view) {
Intent intent =
new
Intent
(
this
, SecondActivity.class
);
ActivityOptions options =
ActivityOptions.makeScaleUpAnimation
(
view, 0
, 0
, view.getWidth
(
), view.getHeight
(
));
startActivity
(
intent, options.toBundle
(
));
}
2. Prérequis▲
Ce qui suit suppose que vous ayiez déjà des notions de développement Android.
Veuillez consulter le tutoriel de développement Android, (tutoriel Developpez : « Tutoriel sur le développement Android ») pour en apprendre les bases. Voir aussi les tutoriels de développement Android pour plus d'informations à ce sujet.
3. Tutoriel : l'animation d'une vue▲
Ce tutoriel démontre l'utilisation de l'API Property Animation.
Créez un nouveau projet Android appelé com.vogella.android.animation.views avec l'activité appelée AnimationExampleActivity. Le fichier de mise en page doit s'appeler main.xml. Modifiez ce fichier comme suit.
<?
xml
version="1.0"
encoding="utf-8"?
>
<
RelativeLayout
xmlns
:
android
=
"
http://schemas.android.com/apk/res/android
"
android
:
id
=
"
@+id/layout
"
android
:
layout_width
=
"
match_parent
"
android
:
layout_height
=
"
match_parent
"
android
:
orientation
=
"
vertical
"
>
<
LinearLayout
android
:
id
=
"
@+id/test
"
android
:
layout_width
=
"
wrap_content
"
android
:
layout_height
=
"
wrap_content
"
>
<
Button
android
:
id
=
"
@+id/Button01
"
android
:
layout_width
=
"
wrap_content
"
android
:
layout_height
=
"
wrap_content
"
android
:
onClick
=
"
startAnimation
"
android
:
text
=
"
Rotate
"
/
>
<
Button
android
:
id
=
"
@+id/Button04
"
android
:
layout_width
=
"
wrap_content
"
android
:
layout_height
=
"
wrap_content
"
android
:
onClick
=
"
startAnimation
"
android
:
text
=
"
Group
"
>
<
/
Button
>
<
Button
android
:
id
=
"
@+id/Button03
"
android
:
layout_width
=
"
wrap_content
"
android
:
layout_height
=
"
wrap_content
"
android
:
onClick
=
"
startAnimation
"
android
:
text
=
"
Fade
"
/
>
<
Button
android
:
id
=
"
@+id/Button02
"
android
:
layout_width
=
"
wrap_content
"
android
:
layout_height
=
"
wrap_content
"
android
:
onClick
=
"
startAnimation
"
android
:
text
=
"
Animate
"
/
>
<
/
LinearLayout
>
<
ImageView
android
:
id
=
"
@+id/imageView1
"
android
:
layout_width
=
"
wrap_content
"
android
:
layout_height
=
"
wrap_content
"
android
:
layout_centerHorizontal
=
"
true
"
android
:
layout_centerVertical
=
"
true
"
android
:
src
=
"
@drawable/icon
"
/
>
<
TextView
android
:
id
=
"
@+id/textView1
"
android
:
layout_width
=
"
wrap_content
"
android
:
layout_height
=
"
wrap_content
"
android
:
layout_above
=
"
@+id/imageView1
"
android
:
layout_alignRight
=
"
@+id/imageView1
"
android
:
layout_marginBottom
=
"
30dp
"
android
:
text
=
"
Large
Text
"
android
:
textAppearance
=
"
?android:attr/textAppearanceLarge
"
/
>
<
/
RelativeLayout
>
Créez la ressource menu suivante.
<?
xml
version="1.0"
encoding="utf-8"?
>
<
menu
xmlns
:
android
=
"
http://schemas.android.com/apk/res/android
"
>
<
item
android
:
id
=
"
@+id/item1
"
android
:
showAsAction
=
"
ifRoom
"
android
:
title
=
"
Game
"
>
<
/
item
>
<
/
menu
>
Modifiez votre activité comme ci-dessous.
package
com.vogella.android.animation.views;
import
android.animation.AnimatorSet;
import
android.animation.ObjectAnimator;
import
android.app.Activity;
import
android.content.Intent;
import
android.graphics.Paint;
import
android.os.Bundle;
import
android.view.Menu;
import
android.view.MenuItem;
import
android.view.View;
import
android.widget.ImageView;
import
android.widget.TextView;
public
class
AnimationExampleActivity extends
Activity {
/**
Appelée
lorsque
l
'
activité
est
créée
.
*
*/
@
Override
public
void
onCreate
(
Bundle savedInstanceState) {
super
.onCreate
(
savedInstanceState);
setContentView
(
R.layout.main);
}
public
void
startAnimation
(
View view) {
float
dest =
0
;
ImageView aniView =
(
ImageView) findViewById
(
R.id.imageView1);
switch
(
view.getId
(
)) {
case
R.id.Button01:
dest =
360
;
if
(
aniView.getRotation
(
) =
=
360
) {
System.out.println
(
aniView.getAlpha
(
));
dest =
0
;
}
ObjectAnimator animation1 =
ObjectAnimator.ofFloat
(
aniView, "
rotation
"
, dest);
animation1.setDuration
(
2000
);
animation1.start
(
);
//
Montre
comment
charger
une
animation
à
partir
de
XML
//
Animation
animation1
=
AnimationUtils.loadAnimation(this,
//
R.anim.myanimation);
//
animation1.setAnimationListener(this);
//
animatedView1.startAnimation(animation1);
break
;
case
R.id.Button02:
//
montre
comment
définir
une
animation
par
le
code
//
utilise
également
un
interpolateur
(BounceInterpolator)
Paint paint =
new
Paint
(
);
TextView aniTextView =
(
TextView) findViewById
(
R.id.textView1);
float
measureTextCenter =
paint.measureText
(
aniTextView.getText
(
).toString
(
));
dest =
0
-
measureTextCenter;
if
(
aniTextView.getX
(
) <
0
) {
dest =
0
;
}
ObjectAnimator animation2 =
ObjectAnimator.ofFloat
(
aniTextView, "
x
"
, dest);
animation2.setDuration
(
2000
);
animation2.start
(
);
break
;
case
R.id.Button03:
//
démontre
la
variation
de
la
couleur
et
l'ajout
d'un
AnimationListener
dest =
1
;
if
(
aniView.getAlpha
(
) >
0
) {
dest =
0
;
}
ObjectAnimator animation3 =
ObjectAnimator.ofFloat
(
aniView, "
alpha
"
, dest);
animation3.setDuration
(
2000
);
animation3.start
(
);
break
;
case
R.id.Button04:
ObjectAnimator fadeOut =
ObjectAnimator.ofFloat
(
aniView, "
alpha
"
, 0f
);
fadeOut.setDuration
(
2000
);
ObjectAnimator mover =
ObjectAnimator.ofFloat
(
aniView, "
translationX
"
, -
500f
, 0f
);
mover.setDuration
(
2000
);
ObjectAnimator fadeIn =
ObjectAnimator.ofFloat
(
aniView, "
alpha
"
, 0f
, 1f
);
fadeIn.setDuration
(
2000
);
AnimatorSet animatorSet =
new
AnimatorSet
(
);
animatorSet.play
(
mover).with
(
fadeIn).after
(
fadeOut);
animatorSet.start
(
);
break
;
default
:
break
;
}
}
@
Override
public
boolean
onCreateOptionsMenu
(
Menu menu) {
getMenuInflater
(
).inflate
(
R.menu.mymenu, menu);
return
super
.onCreateOptionsMenu
(
menu);
}
@
Override
public
boolean
onOptionsItemSelected
(
MenuItem item) {
Intent intent =
new
Intent
(
this
, HitActivity.class
);
startActivity
(
intent);
return
true
;
}
}
Créez une nouvelle activité appelée HitActivity.
package
com.vogella.android.animation.views;
import
java.util.Random;
import
android.animation.Animator;
import
android.animation.AnimatorListenerAdapter;
import
android.animation.AnimatorSet;
import
android.animation.ObjectAnimator;
import
android.app.Activity;
import
android.os.Bundle;
import
android.view.View;
import
android.widget.Button;
public
class
HitActivity extends
Activity {
private
ObjectAnimator animation1;
private
ObjectAnimator animation2;
private
Button button;
private
Random randon;
private
int
width;
private
int
height;
private
AnimatorSet set;
@
Override
protected
void
onCreate
(
Bundle savedInstanceState) {
super
.onCreate
(
savedInstanceState);
setContentView
(
R.layout.target);
width =
getWindowManager
(
).getDefaultDisplay
(
).getWidth
(
);
height =
getWindowManager
(
).getDefaultDisplay
(
).getHeight
(
);
randon =
new
Random
(
);
set =
createAnimation
(
);
set.start
(
);
set.addListener
(
new
AnimatorListenerAdapter
(
) {
@
Override
public
void
onAnimationEnd
(
Animator animation) {
int
nextX =
randon.nextInt
(
width);
int
nextY =
randon.nextInt
(
height);
animation1 =
ObjectAnimator.ofFloat
(
button, "
x
"
, button.getX
(
), nextX);
animation1.setDuration
(
1400
);
animation2 =
ObjectAnimator.ofFloat
(
button, "
y
"
, button.getY
(
), nextY);
animation2.setDuration
(
1400
);
set.playTogether
(
animation1, animation2);
set.start
(
);
}
}
);
}
public
void
onClick
(
View view) {
String string =
button.getText
(
).toString
(
);
int
hitTarget =
Integer.valueOf
(
string) +
1
;
button.setText
(
String.valueOf
(
hitTarget));
}
private
AnimatorSet createAnimation
(
) {
int
nextX =
randon.nextInt
(
width);
int
nextY =
randon.nextInt
(
height);
button =
(
Button) findViewById
(
R.id.button1);
animation1 =
ObjectAnimator.ofFloat
(
button, "
x
"
, nextX);
animation1.setDuration
(
1400
);
animation2 =
ObjectAnimator.ofFloat
(
button, "
y
"
, nextY);
animation2.setDuration
(
1400
);
AnimatorSet set =
new
AnimatorSet
(
);
set.playTogether
(
animation1, animation2);
return
set;
}
}
Si vous exécutez cet exemple et appuyez sur les différents boutons, l'animation devrait démarrer. Vous pouvez naviguer vers vos autres activitésvia l'ActionBar.
4. Les animations de transition de fragment▲
Pendant une transaction de fragment, vous pouvez définir des animations basées sur l'API Property Animation à l'aide de la méthode setCustomAnimations().
Vous pouvez également utiliser plusieurs animations standard fournies par Android via l'appel à la méthode setTransition(). Celles-ci sont désignées par des constantes commençant par FragmentTransaction.TRANSIT_FRAGMENT_*.
Les deux méthodes permettent de préciser une animation de début et une animation de fin.
5. L'API Property Animation pour versions d'Android plus anciennes▲
Jake Wharton a créé une bibliothèque qui permet d'utiliser l'API Property Animation aussi dans les versions d'Android antérieures à la 4.0.
Vous trouverez plus d'informations sur le site Web du projet : NineOldAndroids.
6. Soutenez les tutoriels gratuits vogella▲
Ce tutoriel est libre sous la licence CC BY-NC-SA 3.0 DE. Son code source est distribué sous la Licence publique Eclipse. Voir la page vogella License pour plus de détails sur les conditions de réutilisation.
La rédaction et la mise à jour de ces tutoriels nécessitent beaucoup de travail. Si ce service gratuit de la communauté vous a été utile, vous pouvez soutenir la cause en faisant un don, ainsi qu'en signalant les fautes de frappe et de contenu.
6-1. Merci▲
Si cet article vous a été utile, vous pouvez faire un don à Lars Vogel sur la page de l'article original.
6-2. Questions et discussions▲
Si vous trouvez des erreurs dans ce tutoriel, s'il vous plaît informez-moi (voir en haut de la page). Veuillez noter que, en raison du volume élevé de commentaires que je reçois, je ne peux pas répondre à des questions concernant votre application. Assurez-vous d'avoir lu la FAQ vogella, peut-être la réponse s'y trouve déjà.
7. Liens et littérature▲
7-1. Code source▲
7-2. Ressources animation Android▲
7-3. Ressources vogella▲
- vogella Training : cours Android et Eclipse par l'équipe vogella.
- Tutoriel Android : introduction à la programmation Android (tutoriel Developpez : « Tutoriel sur le développement Android »).
- Tutoriel GWT : programmation en Java et compilation en JavaScript et HTML.
- Tutoriel Eclipse RCP : création d'applications natives en Java.
- Tutoriel JUnit : testez votre application.
- Tutoriel Git : mettez vos fichiers dans un système distribué de gestion de versions.
8. Remerciements Developpez▲
Vous pouvez retrouver l'article original à l'adresse Android Animations - Tutorial. Nous remercions Lars Vogel qui nous a aimablement autorisés à traduire et héberger ses articles. Nous remercions aussi Mishulyna pour sa traduction, Feanorin pour sa relecture technique ainsi que ced pour sa relecture orthographique.
Les commentaires et les suggestions d'amélioration sont les bienvenus, alors, après votre lecture, n'hésitez pas.
Commentez .