Search code examples
javaandroidandroid-studioonclickonclicklistener

What's the issue with my onClickListener?


I am trying to write a simple app that displays a coloured circle which fades to black as it gets further from the centre of the screen. However, whenever I click the app, it crashes. When I remove the onClick code the app runs fine. The only error I can find in logcat is:

Fatal signal 11 (SIGSEGV), code 1, fault addr 0x94 in tid 11955 (raphicstutorial)

And I don't know what to do with that.

Code below:

package com.example.a2dgraphicstutorial;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;

public class MainActivity extends AppCompatActivity {
public class MyView extends View {
    private Canvas thisCanvas;
    private int colourID;
    private Paint fillPaint = new Paint();

    public MyView(Context context){
        super(context);
        colourID = 0;
        fillPaint.setStyle(Paint.Style.FILL);
    }

    public void drawCircle(){
        int x = getWidth();
        int y = getHeight();

        //Drawing the circles
        for (int i = 255;i >= 0;i--){
            //Determining colour
            if (colourID == 0){
                fillPaint.setColor(Color.argb(255,255-i,0,0));
            }
            else if (colourID == 1){
                fillPaint.setColor(Color.argb(255,0,255-i,0));
            }
            else if (colourID == 2){
                fillPaint.setColor(Color.argb(255,0,0,255-i));
            }

            thisCanvas.drawCircle(x/2,y/2,i,fillPaint);
        }

        //Cycling the colourID so the next circle will be a different colour
        colourID = (colourID + 1)%3;
    }

    @Override
    protected void onDraw(Canvas canvas){
        super.onDraw(canvas);
        thisCanvas = canvas;

        //Setting the background to be black
        fillPaint.setColor(Color.parseColor("#000000"));
        thisCanvas.drawPaint(fillPaint);

        //Drawing the first circle
        drawCircle();
    }

}
MyView theScreen;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    theScreen = new MyView(this);
    theScreen.setOnClickListener(new OnClickListener(){
        @Override
        public void onClick(View v){
            theScreen.drawCircle();
        }
    });

    setContentView(theScreen);
}
}

Solution

  • Instead of overriding the onCreate()

    Override onTouchEvent() and listen to a click:

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
    
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //the finger is down do something.....
    
                return true;
    
            case MotionEvent.ACTION_UP:
                //the finger is up do something.....(this is a click)
                //to redraw
                invalidate();
    
                return true;
        }
        return false;
    }
    

    By the way:

    To trigger the onDraw(), call this after a click:

    invalidate();