La aplicación de animaciones sucesivas a ImageView en Android
Pregunta
Me gustaría aplicar animaciones sucesivas (por ejemplo ScaleAnimation) a una ImageView muestra una imagen de recursos. La animación se activa mediante un botón. Por ejemplo, me gustaría ir ampliando progresivamente una imagen sobre cada clic de botón.
he fijado fillAfter = "true" en la animación. Sin embargo, todas las animaciones empiezan desde el estado original de la ImageView. Parece como si el ImageView restablece su estado y la animación es siempre la misma, en lugar de empezar desde el estado final de la animación anterior.
¿Qué estoy haciendo mal?
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button)findViewById(R.id.Button01);
button.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
animate();
}});
}
private void animate() {
ImageView imageView = (ImageView) findViewById(R.id.ImageView01);
ScaleAnimation scale = new ScaleAnimation((float)1.0, (float)1.5, (float)1.0, (float)1.5);
scale.setFillAfter(true);
scale.setDuration(500);
imageView.startAnimation(scale);
}
Solución
Parece como si se restablece el ImageView su estado y la animación es siempre el mismo, en lugar de a partir de la estado final de la animación anterior.
Precisamente! Estoy seguro de que hay un uso para fillAfter="true"
, pero no he descubierto el punto para ello.
Lo que hay que hacer es configurar un AnimationListener
en cada Animation
de relevancia, y hacer algo en onAnimationEnd()
del oyente a persistir en realidad el estado final de la animación. No he jugado con ScaleAnimation
así que no estoy muy seguro de lo que la manera de "persistir el estado final" sería. Si esto fuera un AlphaAnimation
, al pasar de 1.0
a 0.0
, que haría que el INVISIBLE
del widget o GONE
en onAnimationEnd()
, por ejemplo.
Otros consejos
He tenido el mismo problema y ha creado el código siguiente para usar fácilmente diferentes animaciones. Sólo es compatible con la traducción y la alfa niveles por ahora ya que no he utilizado la escala, pero fácilmente podría extenderse para soportar más características.
Me restablecer el desplazamiento y la visibilidad antes de iniciar la animación, pero eso es sólo porque necesitaba de encendido / apagado animaciones.
Y el booleano "dond" está ahí para evitar un desbordamiento de pila en la recursividad (scrollTo llama onAnimationEnd por alguna oscura razón ...)
private void setViewPos(View view, Animation anim, long time){
// Get the transformation
Transformation trans = new Transformation();
anim.getTransformation(time, trans);
// Get the matrix values
float[] values = new float[9];
Matrix m = trans.getMatrix();
m.getValues(values);
// Get the position and apply the scroll
final float x = values[Matrix.MTRANS_X];
final float y = values[Matrix.MTRANS_Y];
view.scrollTo(-(int)x, -(int)y);
// Show/hide depending on final alpha level
if (trans.getAlpha() > 0.5){
view.setVisibility(VISIBLE);
} else {
view.setVisibility(INVISIBLE);
}
}
private void applyAnimation(final View view, final Animation anim){
view.scrollTo(0, 0);
view.setVisibility(VISIBLE);
anim.setAnimationListener(new AnimationListener(){
private boolean doEnd = true;
@Override
public void onAnimationEnd(Animation animation) {
if (doEnd){
doEnd = false;
setViewPos(view, animation, anim.getStartTime() + anim.getDuration());
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationStart(Animation animation) {
}
});
view.startAnimation(anim);
}