【问题标题】:animation does not start in canvas on android动画不会在 android 上的画布中开始
【发布时间】:2010-07-08 12:46:52
【问题描述】:

我正在开发一款需要绘制到 SurfaceView 的游戏 帆布。我正在使用 SurfaceHolder 获取要绘制的 Canvas,并且 在单独的线程中执行绘图。我画的一切都显示 正确,除了这一个动画。

这里是动画定义(在 res/drawable/ my_animation.xml:

这是我将它绘制到画布上的方式:

AnimationDrawable ad = (AnimationDrawable)getResources().getDrawable(R.drawable.my_animation); ad.draw(画布); ad.start();

但只有第一帧出现在屏幕上。

我错过了什么?

谢谢

【问题讨论】:

    标签: android animation canvas


    【解决方案1】:

    如果我的引用正确,您必须将您的 AnimationDrawable 分配给 ImageView,如 http://developer.android.com/reference/android/graphics/drawable/AnimationDrawable.html 中的示例所示:

    // Load the ImageView that will host the animation and
    // set its background to our AnimationDrawable XML resource.
    ImageView img = (ImageView)findViewById(R.id.spinning_wheel_image);
    img.setBackgroundResource(R.drawable.spin_animation);
    
    // Get the background, which has been compiled to an AnimationDrawable object.
    AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground();
    
    // Start the animation (looped playback by default).
    frameAnimation.start()
    

    在您的情况下,您没有将 AnimationDrawable 分配给任何视图,所以我想这就是它没有更新的原因。所以你必须手动调用AnimationDrawable.getFrame(int)

    如果您已经在使用单独的线程,为什么不将动画代码也加入其中?在我看来,这将使您的代码更加一致。

    【讨论】:

      【解决方案2】:

      虽然这是一个老问题,但我也遇到了这个问题并想出了一个解决方法,所以我把它贴在这里以防有人搜索。

      ```java

      final AnimationDrawable animationDrawable = ...;
      
      final View v = new View(this) {
      
          @Override
          protected void onDraw(Canvas canvas) {
              animDrawable.draw(canvas);
          }
      
      };
      
      animationDrawable.setCallback(new Callback() {
      
          @Override
          public void unscheduleDrawable(Drawable who, Runnable what) {
              v.removeCallbacks(what);
          }
      
          @Overridew
          public void scheduleDrawable(Drawable who, Runnable what, long when) {
              v.postDelayed(what, when - SystemClock.uptimeMillis());
          }
      
          @Override
          public void invalidateDrawable(Drawable who) {
              v.postInvalidate();
          }
      });
      

      ```

      【讨论】:

        【解决方案3】:

        各种动画可绘制对象(过渡等)需要Callback 来安排重绘。正如 zhang 演示的那样,这是一个发布 Runnables 的简单接口。

        要在自定义视图中支持动画可绘制对象,您需要做两件事:

        • 将您的视图传递给您的动画 Drawable 的setCallback。甚至 base View 实现了 Drawable.Callback,因此无需编写自己的包装器。
        • 覆盖 verifyDrawable 也为您的动画 Drawable 返回 true。

        至于为什么有人需要它 - 我刚刚在 RecyclerView.ItemDecorations 中实现了动画可绘制支持,这有多酷:-)

        【讨论】:

        • 感谢您的解决方案。它适用于 Android 5.0 及更高版本。但是,如果将翻译转换应用于画布,则该解决方案将无法在 Android 4.4 及更低版本中运行。为了克服这个问题,还应该重写 invalidateDrawable 方法并请求适当区域的失效。
        【解决方案4】:

        您正在使用 Canvas 意味着您在低级编码。在低级别,你必须做所有事情。使用View(ImageView)意味着它是高级别的。在ImageView中已经在canvas的低级定义了如何处理AnimationDrawable。

        【讨论】:

          【解决方案5】:

          Lars Blumberg 的回答是正确的,但文档不正确;您还需要考虑到这一点:animation start issue

          【讨论】:

            最近更新 更多