Pergunta

Gostaria de aplicar animações sucessivas (digamos Scaleanimation) a um ImageView mostrando uma imagem de recurso. A animação é acionada por um botão. Por exemplo, eu gostaria de ampliar de forma incremental uma imagem em cada botão Clique.

Eu defini Fillafter = "true" na animação. No entanto, todas as animações começam no estado original do ImageView. Parece que o ImageView redefine seu estado e a animação é sempre a mesma, em vez de começar do estado final da animação anterior.

O que estou fazendo errado?

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); 
}
Foi útil?

Solução

Parece que o ImageView redefine seu estado e a animação é sempre a mesma, em vez de começar do estado final da animação anterior.

Precisamente! Tenho certeza de que há um uso para fillAfter="true", mas ainda não descobri o ponto para isso.

O que você precisa fazer é configurar um AnimationListener em cada Animation de relevância e fazer algo no ouvinte onAnimationEnd() realmente persistir o estado final de sua animação. Eu não brinquei com ScaleAnimation Portanto, não tenho muita certeza de qual seria a maneira de "persistir o estado final". Se isso fosse um AlphaAnimation, indo de 1.0 para 0.0, você faria o widget INVISIBLE ou GONE dentro onAnimationEnd(), por exemplo.

Outras dicas

Eu tive o mesmo problema e criei o código a seguir para usar facilmente animações diferentes. Ele apenas suporta os níveis de tradução e alfa por enquanto, pois não usei o escala, mas poderia ser facilmente estendido para suportar mais recursos.

Eu redefini o rolo e a visibilidade antes de iniciar a animação, mas isso é apenas porque eu precisava de animações ligadas/desligadas.

E o booleano "Doend" está lá para evitar um transbordamento de pilha na recursão (o ScrollTo chama o ANAMATIONEND por algum motivo obscuro ...)

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);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top