Wie kann ich eine animierte Ansicht in Android zeichnen?

8

Ich habe eine benutzerdefinierte Ansicht von Grund auf erstellt. Erweitert View und übergangen onDraw() . Wenn die Animation animiert wird, erzeuge ich eine benutzerdefinierte Animation mit Offsets. z.B.

%Vor%

Das Denken ist, dass meine Bilder aus der Ungültigkeit kommen. Das Problem besteht darin, dass die Ungültigmachung dieser Ansicht nur durch Scrollen einer Listenansicht auf demselben Bildschirm erfolgen kann.

Diese "shared invalidation ()" verursacht eine Verzögerung meiner Animation. Gibt es einen Ausweg aus dieser Verzögerung?

Haben Sie einen anderen Vorschlag, Animationen in dieser freigegebenen Umgebung auszuführen? Das Erstellen einer Animation mit einem separaten Thread, der den Offset berechnet, erfordert auch erzwungene invalidation () - Aufrufe, um die Animation anzuzeigen (korrigiere mich, wenn ich falsch liege).

Ist die einzige Lösung, um die Animation in zB 10 Ungültigmachungsanfragen mit einem größeren Schritt durchzuführen? Es wird die Verzögerung erleichtern, aber ich denke, dass ich einen anderen Ansatz dafür verwenden kann.

    
weakwire 01.10.2011, 12:15
quelle

2 Antworten

23

"Was am besten ist" hängt natürlich sehr davon ab, was genau Sie tun wollen. Du hast nicht gesagt, was du erreichen willst, also können wir nur raten, was für dich am besten ist.

Hier sind einige einfache Dinge:

  • Wenn Sie Bitmap-Frames animieren möchten, verwenden Sie AnimationDrawable: Ссылка

  • Wenn Sie die Bewegung von Ansichten innerhalb Ihrer Hierarchie animieren möchten, verwenden Sie das View-Animations-Framework: Ссылка

  • Das neue allgemeinere Animationsframework kann viel mehr Sachen machen und ist oft einfacher zu benutzen: Ссылка . Dies ist nativ in Android 3.0+ verfügbar, kann aber auch in der Android-API-Ebene 7 mit der Support-Bibliothek v7 verwendet werden.

  • Wenn Sie ein benutzerdefiniertes Widget schreiben möchten, das ein integrierter Teil seiner Ansichtshierarchie ist und manuell eine eigene Animationszeichnung erstellt, können Sie einen Handler verwenden, um die Updates zu synchronisieren (normalerweise 60 fps oder 20 ms dazwischen) Jede invalidate ()) und dann in Ihrer onDraw () -Methode zeichnen den Status Ihrer Ansicht basierend auf SystemClock.uptimeMillis () als Delta ab dem Beginn der Animation.

Hier ist eine einfache wiederholte Ungültigkeit mit Handler:

%Vor%     
hackbod 16.10.2011 22:28
quelle
4

Da diese Frage interessant ist, werde ich antworten.

Der beste Weg dazu ist ein separater Canvas-Thread. Ein "separater" Canvas kann nur mit SurfaceView erreicht werden. LunarLanding ist ein hervorragendes Beispiel für diesen Einsatz. Jeder Frame wird separat berechnet, nicht nur die Hauptansicht, sondern nur die CPU-Zeit. Daher ist es schneller, sogar mit der Kombination von beispielsweise einer normalen Ansicht oben und einer animierenden Ansicht unten.

Sie müssen jedoch ein Intervall festlegen, wenn Sie sich in dieser gemeinsamen Umgebung befinden. Dieses Intervall wird für die FPS-Obergrenze verwendet. Wenn Sie die FPS-Obergrenze nicht festlegen, wird die CPU in den Ursprungszustand versetzt, um eine gute Animation für SurfaceView zu erhalten, wenn sie alleine war. Wenn Sie es auf 60 fps oder noch weniger beschränken, können Sie alle Ansichten effizient und ohne CPU-Überlastung zeichnen.

Sieh also den Zeichnungs-Thread der Mondlandung aus den API-Demos und setze eine FPS-Begrenzung.

%Vor%

// ps Sie können immer 16 anstelle von 1000 / fps für 60FPS setzen, um die Berechnung jedes Mal zu vermeiden

%Vor%

und dann sieht der Zeichnungs-Thread ungefähr so ​​aus:

%Vor%     
weakwire 12.10.2011 03:15
quelle