2010-12-30 10 views
11

Lassen Sie mich zuerst mein Ziel erklären. Ich versuche, einen Animation zu machen, der die Eigenschaften eines ArcShape ändert. Ein ArcShape's Konstruktor nimmt zwei Felder: startAngle und sweepAngle. Ich möchte die sweepAngle animieren, so dass es auf dem Bildschirm als ein kontinuierlich schrumpfender Kreis erscheint.Android benutzerdefinierte Animation für eine ArcShape

Sie können sich diese Animation vorstellen, indem Sie sich PacMan vorstellen. Stellen Sie sich vor, sein Mund ist geschlossen. Diese Animation wäre vergleichbar damit, dass er seinen Oberkiefer mehr und mehr öffnete, bis es keinen PacMan mehr gab.

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

Jetzt auf die zweite Frage ... Angenommen, ich fand eine Lösung für das erste Problem, wie konnte ich das Animation erstellen? Das ist der Kern das, was ich habe jetzt:

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

Antwort

16

Ich habe eine Lösung gefunden. Ich habe eine Klasse, die erweitert View Wir nennen dies Pacman Ich verschachtelte meine benutzerdefinierte Animation innerhalb dieser Pacman Klasse. Dadurch konnte ich auf die member variables der Pacman Klasse zugreifen.

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

Jetzt, wenn die benutzerdefinierte Animation aktualisiert die Containerklassen mCurrAngle wird onDraw automatisch aufgerufen, die die entsprechende ArcShape zieht.

+4

Ich musste "invalidate();" hinzufügen zur Methode applyTransformation, so dass die Ansicht mit dem neuen Winkel reDraw wird. – marmor

+0

Ich befolgte die Anweisungen, aber meine benutzerdefinierte Ansicht wird nicht auf der Benutzeroberfläche angezeigt. kannst du deinen vollständigen Code posten? –

+2

Ich weiß, ewig alte Post .... Aber ich sehe nicht, wie das den Bogen animiert. Es aktualisiert nur den aktuellen Winkel und dann können Sie es neu zeichnen, aber es ist nicht animiert. Also ... Wie hast du das genau animiert? –

1

Ich glaube, Sie besser dran Drawable erstreckt sein könnten und die draw() Funktion überschreiben die Pfeilung bei jedem Aufruf zu ändern und den entsprechenden Bogen ziehen. Zeichnen wird normalerweise jedes Mal aufgerufen, wenn das Objekt aktualisiert wird, was bedeutet, dass Sie jedes Mal ein neues ArcShape erstellen müssen, wenn es gezeichnet wird. Animation ist mehr für die Durchführung von Transformationen auf Ansichten und anderen UI-Komponenten.

Etwas wie:

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 Sie auf dem richtigen Weg bekommt.

Verwandte Themen