You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

问题根源

  1. onCreateOptionsMenu和onOptionsItemSelected是Activity的生命周期方法,不属于View类,放在MyGraphicView中必然报错。
  2. 移到MainActivity后未生效,是因为缺少@Override注解,系统无法识别为重写方法,且未确保Activity正确处理菜单逻辑。
  3. 额外问题:圆形绘制的半径计算错误,原代码重复计算X轴差值,导致半径异常。

修正方案

  1. 将菜单相关方法移到MainActivity中,添加@Override注解确保正确重写。
  2. 修正圆形半径的计算逻辑,使用标准两点间距离公式。
  3. 切换模式后主动触发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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 14:00:31