1. Nimm jetzt an unserem 2. ADVENT-Gewinnspiel teil - Alle Informationen findest Du hier!

Zeichnen mit SurfaceView und Canvas klappt nicht

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von jonius, 31.03.2012.

  1. jonius, 31.03.2012 #1
    jonius

    jonius Threadstarter Neuer Benutzer

    Beiträge:
    5
    Erhaltene Danke:
    0
    Registriert seit:
    29.03.2012
    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?
     
  2. Unicate, 02.04.2012 #2
    Unicate

    Unicate Android-Experte

    Beiträge:
    473
    Erhaltene Danke:
    57
    Registriert seit:
    09.08.2010
    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
     
    jonius bedankt sich.
  3. jonius, 03.04.2012 #3
    jonius

    jonius Threadstarter Neuer Benutzer

    Beiträge:
    5
    Erhaltene Danke:
    0
    Registriert seit:
    29.03.2012
    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]           
        }
      };
    } 
     
  4. Fr4gg0r, 03.04.2012 #4
    Fr4gg0r

    Fr4gg0r App-Anbieter (Werbung)

    Beiträge:
    2,506
    Erhaltene Danke:
    447
    Registriert seit:
    21.12.2009
    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.
     
  5. jonius, 03.04.2012 #5
    jonius

    jonius Threadstarter Neuer Benutzer

    Beiträge:
    5
    Erhaltene Danke:
    0
    Registriert seit:
    29.03.2012
    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: 04.04.2012
  6. jonius, 10.04.2012 #6
    jonius

    jonius Threadstarter Neuer Benutzer

    Beiträge:
    5
    Erhaltene Danke:
    0
    Registriert seit:
    29.03.2012
    Okay, jetzt habe ich es. Ich habe
    .lockCanvas();
    einfach zu früh aufgerufen, so dass null zurückgegeben wurde...
     
  7. r4in, 18.04.2012 #7
    r4in

    r4in Android-Hilfe.de Mitglied

    Beiträge:
    88
    Erhaltene Danke:
    3
    Registriert seit:
    16.09.2010
    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
     
  8. jonius, 18.04.2012 #8
    jonius

    jonius Threadstarter Neuer Benutzer

    Beiträge:
    5
    Erhaltene Danke:
    0
    Registriert seit:
    29.03.2012
    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();
                }
            }
     
  9. r4in, 19.04.2012 #9
    r4in

    r4in Android-Hilfe.de Mitglied

    Beiträge:
    88
    Erhaltene Danke:
    3
    Registriert seit:
    16.09.2010
    ahhh super, Danke!!
     

Diese Seite empfehlen