Android SurfaceView nicht angezeigt onDraw
Für die Einfachheit der Frage, ich bin Zeichnung ein integer auf einem SurfaceView, die um 1 erhöht jeder Ziehung.
Die Erhöhung ist eigentlich passiert, wie ich sehen kann auf dem System.aus.
Der text auf dem Bildschirm bleibt auf '0'.
Wer kann mir sagen was ich falsch mache?
SurfaceViewTest.java
package com.niek.surfaceviewtest;
import android.app.Activity;
import android.os.Bundle;
public class SurfaceViewTest extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
StatusView.java
package com.niek.surfaceviewtest;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class StatusView extends SurfaceView implements SurfaceHolder.Callback {
private int tmp;
private DrawThread drawThread;
public StatusView(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
setFocusable(true);
drawThread = new DrawThread(getHolder());
}
@Override
public void onDraw(Canvas c) {
c.drawColor(Color.BLACK);
Paint p = new Paint();
p.setColor(Color.RED);
c.drawText(tmp + "", 10, 10, p);
tmp++;
System.out.println(tmp);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
drawThread.setRunning(true);
drawThread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
//we have to tell thread to shut down & wait for it to finish, or else
//it might touch the Surface after we return and explode
boolean retry = true;
drawThread.setRunning(false);
while (retry) {
try {
drawThread.join();
retry = false;
} catch (InterruptedException e) {
//we will try it again and again...
}
}
}
protected class DrawThread extends Thread {
private SurfaceHolder surfaceHolder;
private boolean isRunning;
public DrawThread(SurfaceHolder surfaceHolder) {
this.surfaceHolder = surfaceHolder;
isRunning = false;
}
public void setRunning(boolean run) {
isRunning = run;
}
public void run() {
Canvas c;
while (isRunning) {
c = null;
try {
c = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
onDraw(c);
}
} finally {
//do this in a finally so that if an exception is thrown
//during the above, we don't leave the Surface in an
//inconsistent state
if (c != null) {
surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
}
main.xml
<?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:background="#FFFFFF">
<com.niek.surfaceviewtest.StatusView
android:id="@+id/statusview1"
android:layout_width="fill_parent"
android:layout_height="30dip"
android:background="#000000"
/>
</LinearLayout>
- [thread-necro] Das funktioniert nicht, weil es die Vermischung der Oberfläche und Ansicht Teile der SurfaceView.
onDraw()
wird verwendet, um zu zeichnen, auf der View-Teil, aber für eine SurfaceView der Ansicht sein sollte, eine transparente Loch (benötigt layout-code"), dass können Sie sehen, durch die unabhängige Schicht der Oberfläche hinter sich. Der erste AufrufonDraw()
löscht die Ansicht, Opak schwarz, so dass nichts gerendert auf der Oberfläche ist immer sichtbar. Die Umsetzung oben, kombiniert mit der akzeptierten Antwort unten, die Ergebnisse in einer benutzerdefinierten Ansicht mit unnötigen overhead. Angabe einer Hintergrundfarbe für die Ansicht ist auch eine schlechte Idee.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Meine einzige Vermutung ist, dass die Malerei nicht getan wird, auf die Oberfläche, weil die Ansicht nicht ungültig. Sie nennen soll
invalidate()
, um zu zeichnen, und dann lassen Sie den Rahmen nennenonDraw()
. Vielleicht ist das, warumtmp
wird erhöht, aber die paint-operation erreicht nur die Oberfläche der ersten Zeit.Könnte es sich lohnen, zu Experimentieren: vielleicht machen Sie
Canvas c
MitgliedStatusView
ersetzen und dannmit
Funktioniert das?
postInvalidate()
alle Interaktion mit derSurfaceHolder
stattfinden wird auf dem UI-thread. TutDrawThread
einmal einen Verweis aufSurfaceHolder
überhaupt? Guten Fang.Die aktuelle Lösung ist nicht richtig. Sie sind mit der
SurfaceView
um die Aktualisierung der Inhalte von einem separaten thread und nicht mit derinvalidate()
Methode, die ausgeführt wirdonDraw()
Methode, wenn das system aktualisiert den Inhalt. Das problem ist, dass Sie einen hintergrund für IhreStatusView
, versuchen Sie das löschen, die Zeileoffenbar, müssen Sie die gesamten Informationen in dieser Ansicht.
Sieht, wie Sie sind, zeigen Ihre main.xml mit setContentView(R. layout.main); anstatt die Oberfläche und der Anzeige. es sei denn, ich bin fehlt code irgendwo ich seh das nicht der Fall ist.
R.layout.main
bezieht sich auf die XML-Datei (main.xml), die angibtcom.niek.surfaceviewtest.StatusView
. Ich denke, es sollte funktionieren.