Zeichnen mit SurfaceView und Canvas klappt nicht

  • 8 Antworten
  • Neuster Beitrag
J

jonius

Neues Mitglied
Threadstarter
Ich beginne gerade, mich in der Android-App-Programmierung auszuprobieren und bringe schon ein bisschen Erfahrung mit Java mit.

Ich habe jetzt einmal versucht, nach der Anleitung (Canvas and Drawables | Android Developers) SurfaceView abzuleiten und der/die/das Canvas zu nutzen zum Zeichnen. Dabei bekomme ich aber beim Aufruf von unlockCanvasAndPost() den folgenden Fehler:

Code:
03-31 11:58:41.926: E/AndroidRuntime(557): java.lang.RuntimeException: Unable to start activity ComponentInfo{a.b.c/a.b.c.TestActivity}: android.view.InflateException: Binary XML file line #7: Error inflating class a.b.c.ZeichnerView

Hier der Quellcode:

TestActivity.java

Code:
package a.b.c;

import android.app.Activity;
import android.os.Bundle;

public class TestActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}
ZeichnerView.java
Code:
package a.b.c;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;

public class ZeichnerView extends SurfaceView implements Callback {
    private SurfaceHolder sholder;
    private Canvas canvas;
    
    public ZeichnerView(Context context) {
        super(context);
        sholder = this.getHolder();
        sholder.addCallback(this);
        zeichne();
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width,    int height) {}
    public void surfaceCreated(SurfaceHolder holder) {}
    public void surfaceDestroyed(SurfaceHolder holder) {}
    
    private void zeichne() {
        new Thread() {
            public void run() {
                canvas = sholder.lockCanvas();
                canvas.drawColor(Color.BLUE);
                [B][COLOR=Red]sholder.unlockCanvasAndPost(canvas); [/COLOR]// Hier tritt der Fehler auf[/B]    
            }
        };
    }
}
main.xml
Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <a.b.c.ZeichnerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>
Vermutlich habe ich hier grundsätzlich etwas falsch verstanden. Kann mir jemand weiterhelfen?
 
U

Unicate

Erfahrenes Mitglied
Ich denke ich weiß was falsch ist ^^

Versuch mal in deiner eigenen View den Konstruktor mit 2 Übergabeparametern zu überschreiben. (nicht also View(Context) sondern den anderen mit 2 Parametern)

Dann sollte es gehen
 
J

jonius

Neues Mitglied
Threadstarter
Tatsächlich! Woher weiß ich denn, welcher Konstruktor aufgerufen wird?
Da stellt sich mir gleich die nächste Frage: Warum wird der Hintergrund nicht blau gemalt?
Code:
 private void zeichne() {         
new Thread() {             
  public void run() {                 
    canvas = sholder.lockCanvas();
    [COLOR=Blue][B]canvas.drawColor(Color.BLUE);[/B][/COLOR][COLOR=Black]
    sholder.unlockCanvasAndPost(canvas);[/COLOR]           
    }
  };
}
 
Fr4gg0r

Fr4gg0r

App-Anbieter (Werbung)
weil der Thread garnicht läuft, lol.
Die Frage ist eher, wie du im ersten Post darauf kamst, dass der Fehler in
sholder.unlockCanvasAndPost(canvas); // Hier tritt der Fehler auf
auftritt.
 
J

jonius

Neues Mitglied
Threadstarter
Okay, hatte - warum auch immer - das starten des Prozesses rausgenommen... Also funktioniert es doch noch nicht. Es scheint, als wäre das Canvas-Objekt, das mir übergeben wird null. Ich bekomme nämlich beim Farbesetzen eine NullPointerException.
Code:
    private void zeichne() {
        new Thread() {
            public void run() {
                canvas = sholder.lockCanvas();
                System.out.println(canvas != null);
                canvas.drawColor(Color.BLUE);
                sholder.unlockCanvasAndPost(canvas);                
            }
        }.start();
    }
Dabei auch die Frage: Kann ich irgendwo die Ausgaben von "System.out.println()" sehen?
 
Zuletzt bearbeitet:
J

jonius

Neues Mitglied
Threadstarter
Okay, jetzt habe ich es. Ich habe
.lockCanvas();
einfach zu früh aufgerufen, so dass null zurückgegeben wurde...
 
R

r4in

Ambitioniertes Mitglied
Hallo jonius,

geht das jetzt bei dir, könntest du das vielleicht posten, was du jetzt da verändert hast? Mir wäre damit sehr geholfen :)

Grüße
 
J

jonius

Neues Mitglied
Threadstarter
Ja klar. Ich habe in den Prozess, der für das zeichnen verantwortlich ist eine Abfrage eingefügt, ob das zurückgegebene Canvas-Objekt != null ist. Solange das Fenster nicht bereit ist, wird null übergeben.
Code:
while(true) {
            canvas = holder.lockCanvas();
            if(canvas != null) {
                try {
                    canvas.draw...
                } finally {
                    holder.unlockCanvasAndPost(canvas);
                }                
            }
            
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
 
R

r4in

Ambitioniertes Mitglied
ahhh super, Danke!!
 
Thread starter Similar threads Forum Replies Date
A Android App Entwicklung 7
H Android App Entwicklung 3
Oben Unten