3

I have a surfaceview that catches touchEvents, and then draws a point on the canvas. But when I touch, the SurfaceView changes from red to black, instead of drawing a point. Please take a look at my code:

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;
}
}

Thanks In Advance

EDIT As it turns out, I had to change the line holder.unlockCanvasAndPost(canvas)into mainHolder.unlockCanvasAndPost(canvas). There was still no improvement, but when I try to change the color of the surfaceview with canvas.drawRGB() in drawPoint, it works. Drawing the point however still turns the surfaceview into black.

zeno dhaene
  • 245
  • 3
  • 14
  • Check this answer: http://stackoverflow.com/questions/21311573/surfaceview-shows-black-screen-android/42304462#42304462 – Lucas Miranda Feb 17 '17 at 18:06

3 Answers3

0

When you override onTouch() you need to have a call to super.onTouch(). Might be the problem.

speirs23
  • 127
  • 9
  • onTouch() does not need a super, it only has to return true or false. onTouchEvent() however, does need the super.onTouchEvent(). – zeno dhaene Feb 13 '16 at 16:09
  • http://stackoverflow.com/questions/28979683/android-surfaceview-not-responding-to-touch-events – speirs23 Feb 13 '16 at 16:28
  • I have seen that article, and it solved a problem I had before, but my method is working: it prints out anything as expected. But when I touch the surfaceview for the first time, it turns black, and stays black. – zeno dhaene Feb 13 '16 at 16:30
  • I shared it because you don't seem to follow the directions from the accepted answer. You probably have your reasons. – speirs23 Feb 13 '16 at 16:42
  • Well, I tried it that way, but the the touch wouldn't register. That is not the problem here. Everything works perfectly, except for the drawing part – zeno dhaene Feb 13 '16 at 16:46
  • Yeah, your code looks OK, on a third reading. Weird, this behavior. – speirs23 Feb 13 '16 at 16:57
  • Isn't your 'view' supposed to be a `GameClassic`, not `SurfaceView`: view = (GameClassic) findViewById(R.id.classic_view); – speirs23 Feb 13 '16 at 17:08
  • No, at that point, I am getting the view as a surfaceview, so it can than be pasted in the constructor of the GameClassic class. I have also found the solution which you can read above, thanks for the help! – zeno dhaene Feb 13 '16 at 17:11
0

Apparently, when you lock the canvas and draw on it, the whole canvas gets resetted to its default color, which is black. When you then draw a point on top, the blue was barely visible, which lead me to thinking that the whole screen was getting turned black. Redrawing the background before the point was the solution.

zeno dhaene
  • 245
  • 3
  • 14
  • Well, no. The Surface layer is double- or triple-buffered. You are required to update every pixel inside the dirty region; if you don't specify a dirty region when you lock the Surface, then you have to redraw everything. The screen "reset" to black because you flipped to a buffer that had never been drawn on. – fadden Feb 14 '16 at 16:56
0

At your GameClassic constructor set alpha to zero. Like this:

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

    setFocusable(true);

    setAlpha(0); // this is the secret
}
Derzu
  • 7,011
  • 3
  • 57
  • 60