В чем проблема с моим onClickListener? - PullRequest
0 голосов
/ 09 мая 2020

Я пытаюсь написать простое приложение, которое отображает цветной круг, который становится черным по мере удаления от центра экрана. Однако всякий раз, когда я нажимаю на приложение, оно вылетает. Когда я удаляю код onClick, приложение работает нормально. Единственная ошибка, которую я могу найти в logcat:

Фатальный сигнал 11 (SIGSEGV), код 1, адрес ошибки 0x94 в tid 11955 (raphicstutorial)

И я не Не знаю, что с этим делать.

Код ниже:

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

Ответы [ 3 ]

0 голосов
/ 09 мая 2020

Однажды у меня была проблема, похожая на эту
, и решения заключались в том, чтобы заменить «this» на «имя действия» .class

// replace this to theScreen = new MyView(this);
       theScreen = new MyView(MainActivity.class);



Другое решение - заменить это на « getBaseContext () »

// replace this to theScreen = new MyView(this);
           theScreen = new MyView(getBaseContext());



  1. this контекст возвращает текущий контекст действия, принадлежит к действию, действие уничтожается, тогда оно также уничтожается.
  2. getBaseContext () - это метод ContextWrapper, который является «проксирующей реализацией контекста, которая просто делегирует все свои вызовы другому контексту. Может быть разделена на подклассы. для изменения поведения без изменения исходного контекста. "
0 голосов
/ 09 мая 2020

Эта ошибка возникает, когда вы вызываете Canvas вне метода onDraw, попробуйте этот код

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Display;
import android.view.MotionEvent;
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);
    }

    @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);

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

}
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.invalidate();
        }
    });
    setContentView(theScreen);
}

}

Я переместил метод drawCircle внутрь onDraw и изменил theScreen из вызова drawCircle, чтобы вместо этого позвонить invalidate(), я не уверен, что это тот результат, который вам нужен, но, по крайней мере, это проблема ошибки.

0 голосов
/ 09 мая 2020

Вместо отмены onCreate()

Переопределите onTouchEvent() и прослушайте щелчок:

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

Кстати:

Чтобы вызвать onDraw(), вызовите это после щелчка:

invalidate();
...