ArcShape 的 Android 自定义动画

发布于 2024-10-10 03:18:55 字数 1079 浏览 0 评论 0原文

首先让我解释一下我的目标。我正在尝试制作一个Animation来更改ArcShape的属性。 ArcShape 的 构造函数采用两个字段:startAnglesweepAngle。我想要为 sweepAngle 设置动画,以便它在屏幕上显示为一个不断缩小的圆圈。

您可以通过想象吃豆人来想象这个动画。想象一下他的嘴是闭着的。这个动画类似于他越来越张开上颌,直到不再有吃豆人。

现在...我在实现这个时遇到了一些问题。首先,一旦创建了 ArcShape,就没有内置方法可以更改其 sweepAngle。这引出了我的第一个问题:有没有办法重写 ArcShape 并实现一些 setSweepAngle 方法?或者我是否必须为我希望显示的每个 sweepAngle 创建一个新的 ArcShape

现在讨论第二个问题...假设我找到了第一个问题的解决方案,我该如何创建这个动画?这是我现在所拥有的要点:

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?
  }
}

First let me explain my goal. I am trying to make an Animation that changes the properties of an ArcShape. An ArcShape's constructor takes two fields: startAngle and sweepAngle. I want to animate the sweepAngle so that it appears on screen as a continuously shrinking circle.

You can picture this animation by imagining PacMan. Imagine his mouth is closed. This animation would be akin to him opening his upper jaw more and more until there was no more PacMan.

Now... I have a couple of issues with implementing this. First, once an ArcShape is created, there are no built in methods of changing it's sweepAngle. This brings me to my first question: Is there any way to override ArcShape and implement some setSweepAngle method? Or will I have to create a new ArcShape for each sweepAngle I wish to display?

Now on to the second issue... Assuming I found a solution to the first issue, how could I create this Animation? This is the gist of what I have now:

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?
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

岁月染过的梦 2024-10-17 03:18:55

我找到了解决办法。我有一个扩展 View 的类,我们将其称为 Pacman 我将自定义 Animation 嵌套在这个 Pacman 类中。这允许我访问 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

I have found a solution. I have a class that extends View We'll call this Pacman I nested my custom Animation within this Pacman class. This allowed me to access the member variables of the Pacman class.

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.
    }
  }
}

Now when the custom animation updates the container classes mCurrAngle, onDraw is automatically called, which draws the appropriate ArcShape.

迷你仙 2024-10-17 03:18:55

我认为你最好扩展 Drawable 并重写 draw() 函数来修改每次调用的扫描角度并绘制相应的弧。通常,每次更新对象时都会调用 Draw,这意味着每次绘制时都必须创建一个新的 ArcShape
动画更多的是用于对视图和其他 UI 组件执行转换。

比如:

public class OpenPacman  
{

public OpenPacman(float startAngle, float sweepAngle) {  
    this.mStartAngle = startAngle;  
    this.mSweepAngle = sweepAngle;  
    this.wakaWaka = new ArcShape(this.startAngle, this.mSweepAngle);  
} 

public void draw(Canvas c){  
  //Do drawing stuff here with the canvas
}

//Your other functions for calculating angle, etc and making the ArcShape changes
//Can call these from inside draw function so that when the view that contains your
//object calls draw, it updates correctly.

public float mStartAngle;  
public float msweepAngle;  
private ArcShape wakaWaka;  
}

希望这能让你走上正轨。

I think you might be better off extending Drawable and override the draw() function to modify the sweep angle on each call and draw the corresponding arc. Draw is typically called every time the object is updated, which will mean that you'll have to make a new ArcShape every time it's drawn
Animation is more for performing transformations on Views and other UI components.

Something like:

public class OpenPacman  
{

public OpenPacman(float startAngle, float sweepAngle) {  
    this.mStartAngle = startAngle;  
    this.mSweepAngle = sweepAngle;  
    this.wakaWaka = new ArcShape(this.startAngle, this.mSweepAngle);  
} 

public void draw(Canvas c){  
  //Do drawing stuff here with the canvas
}

//Your other functions for calculating angle, etc and making the ArcShape changes
//Can call these from inside draw function so that when the view that contains your
//object calls draw, it updates correctly.

public float mStartAngle;  
public float msweepAngle;  
private ArcShape wakaWaka;  
}

Hope this gets you on the right track.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文