2016-03-20 7 views
2

Ich habe eine benutzerdefinierte Ansicht, die ein paar Kreise und etwa 10 Bögen zeichnet, die ständig aktualisiert werden (Rotation und Größenänderung). Ich versuche, diesen ganzen Prozess zu animieren, aber ich konnte unter Canvas keine guten Praktiken dafür finden (ich kenne die Grundlagen - benutze dp anstelle von px und so weiter), aber ich weiß nicht, wie ich das richtig machen soll Animationsteil.Best Practices zum Animieren von Formen unter Android Canvas

Momentan durchlaufe ich alle meine Objekte, führe einige Berechnungen durch, um die zukünftige Position zu bestimmen und zeichne sie, aber es sieht abgehackt aus. Hier ist, was ich gerade mache:

@Override 
protected void onDraw(Canvas canvas) { 
    for(Arch arch : arches) { 
     arch.update(); 
     canvas.drawArc(arch.getRect(), -arch.getCurrentRotation(), arch.getSweepAngle(), true, paint); 
    } 

    //logo.draw(canvas); 

    canvas.drawCircle(width/2, height/2, circle_size, paint_opaque); 

    logo.draw(canvas); 

    int textX = (int) (width/2); 
    int textY = (int) ((height/2) - ((paint_text.descent() + paint_text.ascent())/2)); 

    canvas.drawText(text, textX, textY, paint_text); 
    invalidate(); 
} 

Antwort

2

Es gibt einige Dinge, die mit Ihrem Code nicht stimmen.

  1. Sie sollten keine schweren Operationen im onDraw Ihrer benutzerdefinierten aufführen Views. Das ist ein wirklich wichtiger Grundsatz, sich für Android zu entwickeln! Idealerweise sollten Sie innerhalb Ihrer onDraw Methode NUR zeichnen. Manchmal müssen Sie etwas basierend auf Canvas berechnen, aber Sie sollten diese Art von Aktionen auf ein Minimum beschränken. Alles, was Sie vorberechnen und woanders berechnen können (nicht in onDraw), sollten Sie aus Ihrer onDraw extrahieren. In Ihrem Fall arch.update() (die ich vermute, berechnet die nächste "Frame" der Animation) und Berechnung Ihrer textX und textY sollte woanders verschoben werden.

  2. invalidate() bedeutet im Grunde, dass Sie eine Neuzeichnung Ihrer View anfordern. Wenn ein View neu gezeichnet wird, wird sein onDraw aufgerufen. Deshalb sollten Sie nicht invalidate() in Ihrem onDraw anrufen! Wenn jeder einzelne onDraw nach einem anderen onDraw fragt, verursacht dies eine Art Endlosschleife.

  3. Wenn Sie versuchen, eine Rahmenanimation zu erzielen, sollten Sie alle rahmenbezogenen Parameter in einem separaten Thread berechnen, der einige Zeit zwischen den Aktualisierungen wartet und nach jedem einzelnen den Wert invalidate() aufrufen würde.