Animation not starting until UI updates or touch e

2019-03-14 14:49发布

问题:

I have a strange problem with an AlphaAnimation. It is supposed to run repeatedly when an AsyncTask handler is called.

However, the first time the handler is called in the Activity, the animation won't start unless I touch the screen or if the UI is updated (by pressing the phone's menu button for example).

The strange part is that once the animation has run at least once, it will start without problem if the handler is called again.

Here's what the code looks like:

// 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);
}

I have noticed that runOnUIThread isn't necessary (same results occur if I don't use it), but I prefer keeping it as I'm not on the UI thread.

Any ideas on what could cause this?

回答1:

A little more research showed that my problem was the same a this question: Layout animation not working on first run

The flashView's visibility was set to GONE by default (causing the Animation not to start immediately as the View had never been rendered), so I just need to set it to INVISIBLE before calling flashView.startAnimation()



回答2:

If setting the View to VISIBLE won't work, as was in my case, it helped for me to call requestLayout() before starting the Animation, like so:

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

In my case, my View was 0dip high which prevented onAnimationStart from being called, this helped me around that problem.



回答3:

This worked for me:

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

I had to set the view to VISIBLE (not INVISIBLE, neither GONE), causing the view renderization needed to animate it.



回答4:

That's not an easy one. Till you got a real answer : The animation start is triggered by onNetworkEvent. As we don't know the rest of the code, you should look there, try to change onNetworkEvent by an other event that you can easily identify, just to debug if the rest of the code is ok or if it's just the trigger that is responsible for it.



回答5:

May be it will help someone, because previous answers not helped me.

My animation was changing height of view (from 0 to it's real height and back) on click - expand and collapse animations.

Nothing worked until i added listener and set visibility to GONE, when animation ends:

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) {

        }
    });

And when expand just set it to VISIBLE before animation:

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