我的 onClickListener 有什么问题?
What's the issue with my onClickListener?
我正在尝试编写一个简单的应用程序,它显示一个彩色圆圈,当它离屏幕中心越来越远时会逐渐变黑。但是,每当我单击该应用程序时,它就会崩溃。当我删除 onClick 代码时,应用程序运行正常。我在 logcat 中找到的唯一错误是:
Fatal signal 11 (SIGSEGV), code 1, fault addr 0x94 in 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);
}
}
而不是覆盖 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();
曾几何时我遇到过类似的问题
解决方案是将 "this" 替换为 "the name of activity".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());
- this上下文returns当前上下文activity,属于activity, activity 被破坏然后它也会被破坏。
- getBaseContext() 是 ContextWrapper 的方法,它是“代理 Context 的实现,它只是将其所有调用委托给另一个 Context . 可以被 subclassed 修改行为
不改变原来的上下文。"
当您在 onDraw 方法之外调用 Canvas 时会出现该错误,请尝试此代码
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()
,我不确定这是你想要的结果,但至少这是错误的问题。
我正在尝试编写一个简单的应用程序,它显示一个彩色圆圈,当它离屏幕中心越来越远时会逐渐变黑。但是,每当我单击该应用程序时,它就会崩溃。当我删除 onClick 代码时,应用程序运行正常。我在 logcat 中找到的唯一错误是:
Fatal signal 11 (SIGSEGV), code 1, fault addr 0x94 in 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);
}
}
而不是覆盖 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();
曾几何时我遇到过类似的问题
解决方案是将 "this" 替换为 "the name of activity".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());
- this上下文returns当前上下文activity,属于activity, activity 被破坏然后它也会被破坏。
- getBaseContext() 是 ContextWrapper 的方法,它是“代理 Context 的实现,它只是将其所有调用委托给另一个 Context . 可以被 subclassed 修改行为 不改变原来的上下文。"
当您在 onDraw 方法之外调用 Canvas 时会出现该错误,请尝试此代码
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()
,我不确定这是你想要的结果,但至少这是错误的问题。