SurfaceView绘制时变黑

3

我有一个SurfaceView来捕捉触摸事件,然后在画布上绘制一个点。但是当我触摸时,SurfaceView从红色变成黑色,而不是绘制一个点。请看一下我的代码:

GamemodeClassic.java

public class GamemodeClassic extends AppCompatActivity implements Runnable, View.OnTouchListener {

private SurfaceView view;

private GameClassic game;

@Override
protected void onCreate(Bundle savedInstanceState) {
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    super.onCreate(savedInstanceState);
    this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    setContentView(R.layout.activity_gamemode_classic);

    init();
}

public void init() {
    view = (SurfaceView) findViewById(R.id.classic_view);
    game = new GameClassic(this);
    view.getHolder().addCallback(game);
    view.setOnTouchListener(game);
}

@Override
public void run() {

}

@Override
public boolean onTouch(View v, MotionEvent event) {
    return true;
}
}

GameClassic.java

public class GameClassic extends SurfaceView implements SurfaceHolder.Callback, View.OnTouchListener {

SurfaceHolder mainHolder;

public GameClassic(Context context) {
    super(context);

    setFocusable(true);
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    mainHolder = holder;
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    initDraw(holder);
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {

}

public void initDraw(SurfaceHolder holder) {
    Canvas canvas = mainHolder.lockCanvas();
    if(canvas == null) {
        Log.v("testlog", "GameClassic.java - Canvas not available");
    }else{
        Log.v("testlog", "GameClassic.java - Canvas found, drawing");
        canvas.drawRGB(255, 0, 0);
    }

    holder.unlockCanvasAndPost(canvas);
}

public void drawPoint(float x, float y) {
    Canvas canvas = mainHolder.lockCanvas();

    if(canvas != null) {
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.BLUE);

        canvas.drawPoint(x, y, paint);

        mainHolder.unlockCanvasAndPost(canvas);
    }else{
        Log.v("testlog", canvas + "");
    }
}

@Override
public boolean onTouch(View v, MotionEvent event) {
    Log.v("testlog", event.getAction() + "sfsfsf");

    if(event.getAction() == MotionEvent.ACTION_DOWN) {
        drawPoint(event.getX(), event.getY());
        Log.v("testlog", "drawing point on (" + event.getX() + ";" + event.getY() + ")");
    }
    return true;
}
}

谢谢您的提前帮助。

编辑 事实证明,我必须把holder.unlockCanvasAndPost(canvas)这一行改成mainHolder.unlockCanvasAndPost(canvas)。虽然没有改善,但当我试图在drawPoint中用canvas.drawRGB()来改变surfaceview的颜色时,它起作用了。不过,画点仍会使surfaceview变黑。


请查看此答案:https://dev59.com/sHvaa4cB1Zd3GeqPF6jV#42304462 - Lucas Miranda
3个回答

0

显然,当你锁定画布并在其上绘制时,整个画布会被重置为其默认颜色,即黑色。然后在上面绘制一个点时,蓝色几乎不可见,这让我认为整个屏幕都变成了黑色。在绘制点之前重新绘制背景是解决方案。


不是的。Surface层是双缓冲或三缓冲的。您需要更新脏区内的每个像素;如果在锁定Surface时没有指定脏区,则必须重新绘制所有内容。屏幕“重置”为黑色,因为您翻转到一个从未绘制过的缓冲区。 - fadden

0

当你重写 onTouch() 方法时,需要调用 super.onTouch()。这可能是问题所在。


http://stackoverflow.com/questions/28979683/android-surfaceview-not-responding-to-touch-events - speirs23
我看过那篇文章,它解决了我之前遇到的问题,但我的方法也能正常工作:它按预期打印出任何内容。但是当我第一次触摸SurfaceView时,它会变成黑色,并保持黑色。 - zeno dhaene
我分享了它,因为你似乎没有按照被接受的答案的指示去做。你可能有自己的原因。 - speirs23
是的,第三遍阅读你的代码看起来还不错。这个行为很奇怪。 - speirs23
你的“view”不应该是SurfaceView,而应该是GameClassic:view = (GameClassic) findViewById(R.id.classic_view); - speirs23
显示剩余3条评论

0
在你的GameClassic构造函数中将alpha设置为零。像这样:
public GameClassic (Context context) {
    super (context);

    setFocusable(true);

    setAlpha(0); // this is the secret
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接