11 Stimmen

Benutzerdefinierte Android-Animation für ein ArcShape

Lassen Sie mich zunächst mein Ziel erklären. Ich versuche, eine Animation die die Eigenschaften eines ArcShape . Eine ArcShape's Konstruktor benötigt zwei Felder: startAngle y sweepAngle . Ich möchte die Animation sweepAngle so dass er auf dem Bildschirm als kontinuierlich schrumpfender Kreis erscheint.

Sie können sich diese Animation vorstellen, indem Sie sich PacMan vorstellen. Stellen Sie sich vor, sein Mund ist geschlossen. Diese Animation wäre so, als würde er seinen Oberkiefer immer weiter öffnen, bis kein PacMan mehr da ist.

Nun... Ich habe ein paar Probleme mit der Umsetzung dieser. Erstens, sobald ein ArcShape erstellt wird, gibt es keine eingebauten Methoden, um den Wert zu ändern. sweepAngle . Das bringt mich zu meiner ersten Frage: Gibt es eine Möglichkeit, die ArcShape und implementieren einige setSweepAngle Methode? Oder muss ich eine new ArcShape für jede sweepAngle die ich anzeigen möchte?

Nun zum zweiten Problem... Angenommen, ich habe eine Lösung für das erste Problem gefunden, wie könnte ich diese erstellen Animation ? Das ist das Wesentliche, was ich jetzt habe:

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

16voto

dfetter88 Punkte 5331

Ich habe eine Lösung gefunden. Ich habe eine Klasse, die erweitert View Wir nennen das Pacman Ich habe meine benutzerdefinierte Animation innerhalb dieser Pacman Klasse. Dies ermöglichte mir den Zugriff auf die member variables der Pacman clase.

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

Wenn die benutzerdefinierte Animation nun die Containerklassen aktualisiert mCurrAngle , onDraw wird automatisch aufgerufen, wodurch die entsprechende ArcShape .

1voto

Justin Pearce Punkte 4863

Ich denke, es wäre besser, Drawable zu erweitern und die Funktion draw() zu überschreiben, um den Sweep-Winkel bei jedem Aufruf zu ändern und den entsprechenden Bogen zu zeichnen. Draw wird in der Regel jedes Mal aufgerufen, wenn das Objekt aktualisiert wird, was bedeutet, dass Sie jedes Mal, wenn es gezeichnet wird, einen neuen ArcShape erstellen müssen. Animation ist eher für die Durchführung von Transformationen bei Views und anderen UI-Komponenten gedacht.

Etwa so:

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

Ich hoffe, das bringt Sie auf den richtigen Weg.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X