如何在onCreate之后立即启动动画?

hun*_*erp 15 android android-animation

我正在关注http://developer.android.com/guide/topics/graphics/view-animation.html#frame-animation并进行细微更改.我决定制作动画循环并希望它从一开始就开始.

我的动画是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>
Run Code Online (Sandbox Code Playgroud)

和我的初始代码:

 @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();
 };
Run Code Online (Sandbox Code Playgroud)

我看到的只是第一帧而没有其他图像.

Khe*_*dar 47

它已经写在教程中:

重要的是要注意,在Activity的onCreate()方法中,无法调用在AnimationDrawable上调用的start()方法,因为AnimationDrawable尚未完全附加到窗口.

如果您想立即播放动画而不需要交互,那么您可能希望从Activity中的onWindowFocusChanged()方法调用它,当Android将窗口置于焦点时将调用它.

因此,根据您的意愿,将您的呼叫转移到这两个地方中的一个地方.根据您的评论,将您的调用移至onWindowsFocusChanged()内部.

编辑 所以这是"怎么做":

@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));
    }   
}
Run Code Online (Sandbox Code Playgroud)

需要注意的要点是:

  • 不要忘记编写if/else案例来检查焦点
  • 并删除自动生成的"super.onWindowFocusChanged(hasFocus); "

  • 碎片呢?片段中没有onWindowFocusChanged()。 (2认同)

Ron*_*nie 9

设置一个标志onAttachedToWindow() ,然后onWindowFocusChanged()检查它并启动动画.

@Override
void onWindowFocusChanged(boolean hasFocus) {
    if (hasFocus & mbFlag) {
        // start animation.
    }
}
Run Code Online (Sandbox Code Playgroud)

更新

只需扩展ImageView类和覆盖onFocusChange方法即可.然后在您的活动中通过调用将焦点设置为它animImg.requestFocus().动画应该在聚焦时开始.确保您的imageview具有可调焦性.

如果这不起作用,您可能还想覆盖该onAttachedToWindow()方法.在那里设置一个标志并在开始动画之前检查.

@Override
void onFocusChange(boolean hasFocus) {
    if (hasFocus) {
        // start animation.
    }
}
Run Code Online (Sandbox Code Playgroud)


Muz*_*ant 5

您可以在活动中使用post任何方法View。它可能看起来应该像这样:

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


hun*_*erp -18

在 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;
            }
        }
Run Code Online (Sandbox Code Playgroud)

  • 我不知道是谁说的那么负面,但是这段代码有严重的问题,你永远不会在 UI 线程之外更新 UI 对象。检查 doInBackground() 是否在 UI 线程外部执行。 (4认同)
  • 关键是这段代码是错误的,并且你没有正确阅读 android 文档。Stackoverflow 并不是一场谁更了解什么的竞赛,这个网站的宗旨是帮助他人,至少我就是这样使用它的,而且我在这里学到了很多东西。所以下次要多考虑一下那些浪费自己宝贵时间来帮助你的人。 (3认同)
  • 它有效,但它是一个 hacky 解决方案。您希望活动在后台线程运行之前完成设置,从而创建竞争条件。它可能在设备上运行,但不能保证在未来版本的 Android 中不会发生某些变化,并且竞争条件将导致它开始失败。 (3认同)