2010-05-04 21 views
7

auftritt Wie kann ich onDraw so überschreiben, dass ich das, was (als Bitmap) gezogen worden wäre, und sie verändern?außer Kraft setzen OnDraw zu ändern, wie die Zeichnung (Android)

Die Methode unten funktioniert, aber es leider beinhaltet dieses Verfahren eine Bitmap, die Größe des gesamten Bildschirms zu schaffen - nicht nur den Bereich, der gezogen wird. Wenn ich das UI-Elemente zu zeichnen verwenden, ist es neu gezeichnet für jedes Oberflächenelement. Kann dies effizienter gemacht werden?

@Override 
protected void onDraw(Canvas canvas) { 
    //TODO: Reduce the burden from multiple drawing 
    Bitmap bitmap=Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Config.ARGB_8888); 
    Canvas offscreen=new Canvas(bitmap); 
    super.onDraw(offscreen); 
    //Then draw onscreen 
    Paint p=new Paint(); 
    p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN)); 
    canvas.drawBitmap(bitmap, 0, 0, p); 
} 

Antwort

7

wird der folgende Code viel effizienter sein.

public class MyView extends TextView{ 
    private Canvas offscreen; 

    public MyView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    public MyView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public MyView(Context context) { 
     super(context); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     //We want the superclass to draw directly to the offscreen canvas so that we don't get an infinitely deep recursive call 
     if(canvas==offscreen){ 
      super.onDraw(offscreen); 
     } 
     else{ 
      //Our offscreen image uses the dimensions of the view rather than the canvas 
      Bitmap bitmap=Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_8888); 
      offscreen=new Canvas(bitmap); 
      super.draw(offscreen); 
      //Create paint to draw effect 
      Paint p=new Paint(); 
      p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN)); 
      //Draw on the canvas. Fortunately, this class uses relative coordinates so that we don't have to worry about where this View is actually positioned. 
      canvas.drawBitmap(bitmap, 0, 0, p); 
     } 
    } 
} 
+0

Wird nicht zu viele Garbage Collection erstellt, wenn neue Objekte in der Zeichenmethode erstellt werden? – Srin

8

Haben Sie versucht, die Größe des Bitmap Ändern Sie erstellen, werden nur gleich den Clip Grenzen eher als die gesamte Größe des gegebenen Leinwand? Ich weiß nicht, ob das bei allen Views der Fall ist, aber ich habe festgestellt, dass die onDraw-Methode für einige Views eine Leinwand hat, die so groß ist wie der Bildschirm, unabhängig von der tatsächlichen Größe des Inhalts. Dann wird die Leinwand geclippt, nur auf die linke obere Ecke beschränkt, dort gezeichnet und dann an anderer Stelle auf dem Bildschirm übertragen, wenn sie tatsächlich bereit ist, das gesamte Layout anzuzeigen. Mit anderen Worten, trotz einer Leinwand, die die Größe des gesamten Bildschirms hat, verwendet sie nur ein kleines Stück davon. Also, was Sie könnten versuchen, ist zu tun, anstatt

Bitmap bitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), ...) 

verwenden Sie

Rect rect = canvas.getClipBounds(); 
int width = rect.width(); 
int height = rect.height(); 
Bitmap bitmap = Bitmap.createBitmap(width, height, ...); 

Auf diese Weise versuchen, könnten Sie den Aufwand für die Arbeit mit einem viel größeren Bitmap als nötig zu reduzieren. Hinweis: Ich habe das nicht wirklich versucht, es funktioniert also vielleicht nicht, aber es ist einen Versuch wert.

+0

Ich denke 'getClipBounds' Methode der richtigen Dimensionen gibt, aber da ich mich mit den' View' des 'getWidth' und' getHeight' Methoden nicht sicher bin, ging. Dies ist eigentlich nicht als 'onDraw' Methode arbeiten verwendet eine Art von Offset. Ich habe es geschafft, dies zu lösen, indem ich einen netten Trick mit der "draw" -Methode von "View" verwende, die keine Offsets verwendet. Beachten Sie, dass die Draw-Methoden eines Canvas alle Offsets verwenden. Ich fand das zuerst verwirrend, aber es macht alles Sinn, wenn man darüber nachdenkt. – Casebash

0

begegnete ich etwas ähnliches, wo canvas.getWidth() und canvas.getHeight(), um die Breite und Höhe des gesamten Bildschirms kehrt anstelle der Ansicht selbst.

Versuchen Sie, die unten stattdessen zu verwenden:

Bitmap bitmap=Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_8888); 

Für meinen Fall getWidth() und getHeight() gibt mir die Dimensionen meiner Sicht. Viel Glück!

Verwandte Themen