简体   繁体   中英

How to start Animation immediately after onCreate?

I am following http://developer.android.com/guide/topics/graphics/view-animation.html#frame-animation with minor changes. I have decided to make the animation loop and want it to start from the get-go.

My animation is at drawable/listening.xml:

<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item
    android:drawable="@drawable/l_01"
    android:duration="200" />
<item
    android:drawable="@drawable/l_02"
    android:duration="200" />
<item
    android:drawable="@drawable/l_03"
    android:duration="200" />
</animation-list>

and my init code:

 @Override public void onWindowFocusChanged(boolean hasFocus)  { 
      super.onWindowFocusChanged(hasFocus); 
      animImg = (ImageView)findViewById(R.id.listen_anim);
      animImg.setBackgroundResource(R.drawable.listening);
      anim = (AnimationDrawable) animImg.getBackground(); 
      anim.start();
 };

All I see is the first frame and no other images.

It's already written in the tutorial:

It's important to note that the start() method called on the AnimationDrawable cannot be called during the onCreate() method of your Activity, because the AnimationDrawable is not yet fully attached to the window.

If you want to play the animation immediately, without requiring interaction , then you might want to call it from the onWindowFocusChanged() method in your Activity, which will get called when Android brings your window into focus.

So move your call to start in one of those two places, depending on your wish. Based on your comment, move your call to start inside onWindowsFocusChanged() .

EDIT So this is "How to do it" :

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    if(hasFocus){
        textView.startAnimation(AnimationUtils.loadAnimation(MainActivity.this,
            android.R.anim.slide_in_left|android.R.anim.fade_in));
    }   
}

The points to pay attention to are:

  • do not forget to write the if/else case to check the focus
  • and delete the auto-generated "super.onWindowFocusChanged(hasFocus); "

Have a flag set in onAttachedToWindow() and then in onWindowFocusChanged() check it and start the animation.

@Override
void onWindowFocusChanged(boolean hasFocus) {
    if (hasFocus & mbFlag) {
        // start animation.
    }
}

Update

Simply extend the ImageView class and override onFocusChange method. Then in your activity set the focus to it by calling animImg.requestFocus() . The animation should start when it gets focused. Make sure your imageview is focusable.

If this does not work, you may want to override the onAttachedToWindow() method also. Set a flag in there and check before starting the animation.

@Override
void onFocusChange(boolean hasFocus) {
    if (hasFocus) {
        // start animation.
    }
}

You can use the post method of any View on the activity. It should probably look like this:

View anyView = findViewById(R.id.anyView);
anyView.post(new Runnable()
{
    @Override
    public void run()
    {
        // Your code goes here
    }
});

As this question was asked some long time ago, I have encounter same problem in 2019 with usage of transitions-Everywhere or AndroidX Transitions. And the only solution for me was to use @Muzikant answer. Simply call in your onCreate()

rootViewOfYourLayout.post {
            TransitionManager.beginDelayedTransition(rootViewOfYourLayout)
            someViewId.visibility = View.VISIBLE
        }

And it works perfectly, for example in my case for Splash screen.

Update
As after some testing, it appears this solution has minor issue. Animation is started and you block the phone or move app to background, and in result when app again in foreground it's just frozen as no TransitionListener callbacks received, so in my case onTransitionEnd() wasn't called where was located logic to navigate user to next screen.

For now this works for me without problems :

  override fun onWindowFocusChanged(hasFocus: Boolean) {
   if(hasFocus && isAnimationStarted.not()){
   rootViewOfYourLayout.post {
          TransitionManager.beginDelayedTransition(rootViewOfYourLayout)
          someViewId.visibility = View.VISIBLE
            }
  }
}

You need to give time to UI manager create appropiate resources BEFORE starting animation. Correct pattern is

a) Create animation object in onCreate.
b) Start animation object elsewhere.

Don't create and start in same method.

animation = AnimationUtils.loadAnimation(this, R.anim.push_left_out);

yourobject.startanimation(animation);

This may help

Run this in onResume():

class AnimTask extends AsyncTask<String, String,String> {
            Activity act;
            AnimTask(Activity act) {
                this.act = act;
            }

            @Override
            protected String doInBackground(String... params) {
                act.runOnUiThread(new Runnable() {
                    public void run(){
                        animImg = (ImageView)findViewById(R.id.listen_anim);
                        animImg.setBackgroundResource(R.drawable.listening);
                        anim = (AnimationDrawable) animImg.getBackground();
                        anim.start();
                    }
                });
                return null;
            }
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM