Android开发:View中无法解析onCreateOptionsMenu,菜单显示异常求助
解决Canvas绘图选项菜单无法显示及模式切换问题
问题描述
开发带选项菜单的Canvas绘图功能,期望通过菜单切换直线/圆形绘制模式,但菜单无法正常显示。报错提示Cannot resolve method 'onCreateOptionsMenu' in 'View',onOptionsItemSelected方法也存在相同问题。尝试将菜单代码移到MainActivity中仍未解决,原代码如下:
public class MainActivity extends AppCompatActivity { final static int LINE = 1, CIRCLE = 2; static int curShape = LINE; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new MyGraphicView(this)); } public class MyGraphicView extends View{ int startX = -1, startY = -1, stopX = -1, stopY = -1; public MyGraphicView(Context context) { super(context); } public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: startX = (int) event.getX(); startY = (int) event.getY(); break; case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_UP: stopX = (int) event.getX(); stopY = (int) event.getY(); this.invalidate(); break; } return true; } @Override protected void onDraw(Canvas canvas){ super.onDraw(canvas); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setStrokeWidth(5); paint.setStyle(Paint.Style.STROKE); paint.setColor(Color.RED); switch (curShape) { case LINE: canvas.drawLine(startX, startY, stopX, stopY, paint); break; case CIRCLE: int radius = (int) (Math.sqrt(Math.pow(stopX-startX, 2)) +Math.sqrt(Math.pow(stopX-startX, 2))); canvas.drawCircle(startX, startY, radius, paint); break; } } public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); menu.add(0, 1, 0, "Drawing line"); menu.add(0, 2, 0, "Drawing circle"); return true; } public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case 1: curShape = LINE; return true; case 2: curShape = CIRCLE; return true; } return super.onContextItemSelected(item); } } }
问题根源
onCreateOptionsMenu和onOptionsItemSelected是Activity的生命周期方法,不属于View类,放在MyGraphicView中必然报错。- 移到MainActivity后未生效,是因为缺少
@Override注解,系统无法识别为重写方法,且未确保Activity正确处理菜单逻辑。 - 额外问题:圆形绘制的半径计算错误,原代码重复计算X轴差值,导致半径异常。
修正方案
- 将菜单相关方法移到MainActivity中,添加
@Override注解确保正确重写。 - 修正圆形半径的计算逻辑,使用标准两点间距离公式。
- 切换模式后主动触发View重绘,保证绘制模式立即生效。
修正后的完整代码
import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { final static int LINE = 1, CIRCLE = 2; static int curShape = LINE; private MyGraphicView graphicView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); graphicView = new MyGraphicView(this); setContentView(graphicView); } @Override public boolean onCreateOptionsMenu(Menu menu) { menu.add(0, 1, 0, "Drawing line"); menu.add(0, 2, 0, "Drawing circle"); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case 1: curShape = LINE; graphicView.invalidate(); return true; case 2: curShape = CIRCLE; graphicView.invalidate(); return true; default: return super.onOptionsItemSelected(item); } } public class MyGraphicView extends View { int startX = -1, startY = -1, stopX = -1, stopY = -1; public MyGraphicView(Context context) { super(context); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: startX = (int) event.getX(); startY = (int) event.getY(); break; case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_UP: stopX = (int) event.getX(); stopY = (int) event.getY(); this.invalidate(); break; } return true; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setStrokeWidth(5); paint.setStyle(Paint.Style.STROKE); paint.setColor(Color.RED); switch (curShape) { case LINE: if (startX != -1 && stopX != -1) { canvas.drawLine(startX, startY, stopX, stopY, paint); } break; case CIRCLE: if (startX != -1 && stopX != -1) { int radius = (int) Math.sqrt(Math.pow(stopX - startX, 2) + Math.pow(stopY - startY, 2)); canvas.drawCircle(startX, startY, radius, paint); } break; } } } }
关键修改点
- 菜单方法移至MainActivity并添加
@Override,确保系统调用正确的生命周期方法。 - 切换模式后调用
graphicView.invalidate(),强制View重绘以更新绘制模式。 - 修正圆形半径计算逻辑,使用标准两点间距离公式。
- 添加绘制前的非空判断,避免初始状态下的无效绘制。
内容的提问来源于stack exchange,提问作者slprbrck
相关产品推荐
相关产品推荐

