Для простоты вопроса я рисую целое число в SurfaceView, которое увеличивается на 1 при каждом рисовании. Увеличение действительно происходит, как я вижу на System.out. Текст на экране остается на «0». Кто может сказать мне, что я делаю неправильно?
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>
onDraw()
используется для рисования в части View, но для SurfaceView View должен быть прозрачным отверстием (необходимым для кода макета), которое позволяет вам видеть независимый слой Surface позади. Первый вызовonDraw()
очищает View до непрозрачного черного цвета, поэтому ничего, отображаемое на Surface, никогда не будет видно. Вышеприведенная реализация в сочетании с принятым ответом ниже приводит к пользовательскому представлению с ненужными накладными расходами. Указание фона для представления также является плохой идеей. - person fadden   schedule 09.09.2015