适用于ArcShape的Android自定义动画


问题内容

首先让我解释一下我的目标。我试图使Animation改变的属性ArcShape。一个ArcShape's构造函数有两个领域:startAnglesweepAngle。我想设置动画sweepAngle,使其在屏幕上显示为不断缩小的圆圈。

您可以通过想象PacMan来描绘此动画。想象一下他的嘴巴是闭合的。这种动画效果类似于他越来越张开上颚,直到不再有吃豆人为止。

现在…我在实现此问题上有两个问题。首先,ArcShape创建后,就没有内置的更改方法sweepAngle。这使我想到了第一个问题:是否有任何方法可以覆盖ArcShape和实现某些setSweepAngle方法?还是我必须new ArcShape为每个sweepAngle要显示的内容创建一个?

现在转到第二个问题…假设我找到了第一个问题的解决方案,那么我该如何创建它Animation呢?这是我现在拥有的要点:

public class OpenPacman extends Animation {
  public OpenPacman(float startAngle, float sweepAngle) {
    mStartAngle = startAngle;
    mSweepAngle = sweepAngle;
  }

  @Override
  protected void applyTransformation(float interpolatedTime, Transformation t) {
    /* This represents the current sweepAngle */
    float currAngle = mStartAngle + ((mSweepAngle - mStartAngle) * interpolatedTime);

    //Now I need to update the ArcShape's sweepAngle to currAngle. But HOW?
  }
}

问题答案:

我找到了解决方案。我有一个扩展的类,View我们称其为Pacman我的自定义嵌套AnimationPacman该类中。这让我访问member variables了的Pacman类。

public class Pacman extends View {
  float mSweepAngle;
  ...
  //include constructors
  //override onMeasure
  ...

  /* Here we override onDraw */
  @Override
  protected void onDraw(final Canvas canvas) {
    Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
    RectF oval = new RectF(canvas.getClipBounds());
    canvas.drawArc(oval, 0, mCurrAngle, true, p);
  }

  /* Here we define our nested custom animation */
  public class OpenPacman extends Animation {
    float mStartAngle;
    float mSweepAngle;

    public OpenPacman (int startAngle, int sweepAngle, long duration) {
      mStartAngle = startAngle;
      mSweepAngle = sweepAngle;
      setDuration(duration);
      setInterpolator(new LinearInterpolator());
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
      float currAngle = mStartAngle + ((mSweepAngle - mStartAngle) * interpolatedTime);
      Pacman.this.mCurrAngle = -currAngle; //negative for counterclockwise animation.
    }
  }
}

现在,当自定义动画更新容器类时mCurrAngle,会onDraw被自动调用,从而绘制相应的ArcShape