web-dev-qa-db-fra.com

L'animation ne commence pas avant la mise à jour de l'interface utilisateur ou l'événement tactile

J'ai un problème étrange avec un AlphaAnimation. Il est supposé s'exécuter de manière répétée lorsqu'un gestionnaire AsyncTask est appelé.

Cependant, la première fois que le gestionnaire est appelé dans Activity, l'animation ne démarrera que si je touche l'écran ou si l'interface utilisateur est mise à jour (en appuyant sur le bouton de menu du téléphone, par exemple).

La partie étrange est qu’une fois que l’animation a été exécutée au moins une fois, elle démarrera sans problème si le gestionnaire est appelé à nouveau.

Voici à quoi ressemble le code:

// AsyncTask handler
public void onNetworkEvent()
{
  this.runOnUiThread(new Runnable() {
    @Override
    public void run()
    {
      flashScreen(Animation.INFINITE);
    }
  });
}

// Called method
private void flashScreen(int repeatCount)
{
  final View flashView = this.findViewById(R.id.mainMenuFlashView);

  AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
  alphaAnimation.setRepeatCount(repeatCount);
  alphaAnimation.setRepeatMode(Animation.RESTART);
  alphaAnimation.setDuration(300);
  alphaAnimation.setInterpolator(new DecelerateInterpolator());
  alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
    @Override
    public void onAnimationStart(Animation animation)
    {
      flashView.setVisibility(View.VISIBLE);
    }

    @Override
    public void onAnimationEnd(Animation animation)
    {
      flashView.setVisibility(View.GONE);
    }

    @Override
    public void onAnimationRepeat(Animation animation) { }
  });

  flashView.startAnimation(alphaAnimation);
}

J'ai remarqué que runOnUIThread n'est pas nécessaire (les mêmes résultats se produisent si je ne l'utilise pas), mais je préfère le conserver car je ne suis pas sur le fil de l'interface utilisateur.

Des idées sur ce qui pourrait causer ceci?

26
Jukurrpa

Un peu plus de recherches ont montré que mon problème était le même à cette question: L'animation de la mise en page ne fonctionne pas à la première utilisation

La visibilité de flashView a été définie par défaut sur GONE (le Animation ne démarrant pas immédiatement car la View n'a jamais été rendue), je dois donc le définir sur INVISIBLE avant d'appeler flashView.startAnimation()

43
Jukurrpa

Si régler View sur VISIBLE ne fonctionne pas, comme cela a été mon cas, il m’a aidé d’appeler requestLayout() avant de démarrer Animation, comme ceci:

Animation an = new Animation() {
...   
view.requestLayout();
view.startAnimation(an);

Dans mon cas, ma View était 0dip élevé, ce qui empêchait l'appel de onAnimationStart, ce qui m'a aidé à résoudre ce problème.

26
Zebaz

Cela a fonctionné pour moi:

view.setVisibility(View.VISIBLE);
view.startAnimation(animation);

Je devais définir view sur VISIBLE (pas INVISIBLE, ni GONE), ce qui entraînait le rendu de la vue nécessaire pour l'animer.

2
Mario Velasco

Peut-être que cela aidera quelqu'un, parce que les réponses précédentes ne m'ont pas aidé.

Mon animation changeait la hauteur de vue (de 0 à sa hauteur réelle et inversement) lors du clic - développer et réduire les animations.

Rien n'a fonctionné jusqu'à ce que j'aie ajouté auditeur et défini la visibilité sur GONE, à la fin de l'animation:

collapseAnim.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationEnd(Animation animation) {
            view.setVisibility(View.GONE);
        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    });

Et quand expand, il suffit de le définir sur VISIBLE avant l'animation:

 view.setVisibility(View.VISIBLE);
 view.startAnimation(expandAnim);
0
Vadim

Ce n'est pas facile. Jusqu'à ce que vous ayez une vraie réponse: le début de l'animation est déclenché par onNetworkEvent. Comme nous ne connaissons pas le reste du code, vous devriez y regarder, essayez de modifier onNetworkEvent par un autre événement facilement identifiable, il suffit de déboguer si le reste du code est correct ou s'il responsable pour cela.

0
TheBeps