Ich arbeite an einer benutzerdefinierten Ansicht für eine Android-Anwendung, die dem analogen Gauge-Beispielcode von Achte auf den Roboter .
Wenn ich den Code von der gelisteten Seite aus führe, sehe ich das auf meinem Bildschirm:
(Motorola Droid, 2.2.3), (Emulator, 4.0.3)
(Xoom, 4.0.3) (Anderes Telefon, 4.0.3)
Die Hand fehlt!
Die Zeichnungsaufrufe werden ausgeführt (ich kann sie in logcat sehen), aber die Canvas-Elemente, die die Aufrufe zeichnen, sind unsichtbar.
Es ist jedoch nicht abhängig von der API-Ebene ; Wenn ich es richtig in ein Projekt importiere, wird es bei der Ausführung auf dem Xoom angezeigt.
Wenn ich die Dateien jedoch in einen anderen Projektordner verschiebe (derselbe Quellcode, dieselben Layouts), wird das Wählrad nicht mehr angezeigt.
Was ist los? Wie könnte derselbe Code unterschiedliche Ergebnisse auf verschiedenen Geräten erzeugen?
Der Schlüssel zu meinem Geheimnis schien also zu sein, dass es am Emulator funktioniert hat, aber nicht an den Hardware-Geräten.
Ich habe die Hardware-Rendering-Seite auf der Website des Android-Entwicklers durchgelesen, aber anscheinend nicht genau genug.
Obwohl erwähnt wird, dass die APIs ab Version 11 verfügbar sind, heißt es nicht, dass Hardware-Rendering standardmäßig für alle Anwendungen aktiviert ist, beginnend mit API Level 14 (ICS) . p>
Was bedeutet das für uns?
Fast alles ist schneller; außer den wenigen Dingen, die nicht funktionieren.
Ich habe es geschafft, zwei davon zu verletzen, ohne es zu merken:
Es ist nicht in der API-Referenz erwähnt (oder irgendwo anders ich finden kann, und sicherlich nicht von Lint überprüft), aber mit einer der aufgeführten Operationen kann seltsame Dinge tun.
In meinem Fall schien Canvas.DrawTextOnPath () gut zu funktionieren.
Aber wenn Android feststellt, dass die Farbe, die ich auf der Hand verwendet habe, eine Schattenebene aufweist, wird sie ignoriert.
Aus dem obigen Dokumentationslink:
Es gibt zwei verschiedene Möglichkeiten, um zu überprüfen, ob die Anwendung hardwarebeschleunigt ist:
- View.isHardwareAccelerated () gibt "true" zurück, wenn die Ansicht an ein hardwarebeschleunigtes Fenster angehängt ist.
- Canvas.isHardwareAccelerated () gibt true zurück, wenn der Canvas hardwarebeschleunigt ist
Wenn Sie diesen Zeichencode einchecken müssen, verwenden Sie Canvas.isHardwareAccelerated () anstelle von & gt; View.isHardwareAccelerated (), wenn möglich. Wenn eine Ansicht an ein beschleunigtes Hardware- & gt; -Fenster angehängt ist, kann sie immer noch mit einem nicht hardwarebeschleunigten Canvas gezeichnet werden. Dies geschieht zum Beispiel beim Zeichnen einer Ansicht in eine Bitmap für Caching-Zwecke.
In meinem Fall scheint das Gegenteil eingetreten zu sein. Die benutzerdefinierte Ansicht protokolliert, dass sie nicht hardwarebeschleunigt ist. Die Zeichenfläche meldet jedoch, dass sie hardwarebeschleunigt ist.
Der einfachste Fix erzwingt, dass die benutzerdefinierte Ansicht Software-Rendering ausführt. Per der Dokumentation kann dies erreicht werden durch:
%Vor%Alternativ können Sie die fehlerhaften Vorgänge entfernen und das Hardware-Rendering aktiviert lassen.
Lerne von meinem Unglück. Viel Glück, alles.
Mit myView.setLayerType (View.LAYER_TYPE_SOFTWARE, null); Vorschlag Ich kann die Hand sehen. Aber ich habe noch ein Problem: Ich sehe Skalierung mit nur 0 geschrieben! Wie im Bild und zwei strage Nullen aus dem Schema: (GALAXY NEXUS 4.2.1)
Meine drawScale () -Methode ist wie im Beispiel:
%Vor%in meinem Fall habe ich das gemacht:
%Vor%wo SetData in AnalogView
ist %Vor%Tags und Links android android-canvas android-emulator android-view