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

Android开发:点击MenuItem为已有Canvas添加图形的实现问题

解决方案:点击MenuItem给Canvas添加图形

核心逻辑

  • 用集合存储所有需要绘制的图形数据,避免onDraw仅绘制固定内容
  • 点击菜单时添加新图形数据,调用invalidate()触发View重绘,让新图形显示

修改后的完整代码

public class MainActivity extends AppCompatActivity {
    // 将MyView声明为成员变量,方便菜单点击时访问
    private MyView myView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        myView = new MyView(this);
        setContentView(myView);
        // 初始化添加第一条线
        myView.addLine(200, 300, 280, 450);
    }

    public class MyView extends View {
        // 用集合存储所有线条数据
        private List<Line> lineList = new ArrayList<>();
        private Paint myPaint;

        public MyView(Context context) {
            super(context);
            // 初始化Paint,避免每次onDraw重复创建
            myPaint = new Paint();
            myPaint.setColor(Color.BLUE);
            myPaint.setStrokeWidth(8);
        }

        // 添加线条的方法
        public void addLine(float startX, float startY, float endX, float endY) {
            lineList.add(new Line(startX, startY, endX, endY));
            // 触发重绘
            invalidate();
        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            // 遍历集合绘制所有线条
            for (Line line : lineList) {
                canvas.drawLine(line.startX, line.startY, line.endX, line.endY, myPaint);
            }
        }

        // 自定义内部类存储线条参数
        private class Line {
            float startX, startY, endX, endY;

            Line(float startX, float startY, float endX, float endY) {
                this.startX = startX;
                this.startY = startY;
                this.endX = endX;
                this.endY = endY;
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menuP) {
        getMenuInflater().inflate(R.menu.menu, menuP);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem option_menu) {
        int id = option_menu.getItemId();
        if (id == R.id.addDraw) {
            // 添加一条新的线条(这里用随机坐标示例,可替换成你需要的图形参数)
            float startX = (float) Math.random() * getResources().getDisplayMetrics().widthPixels;
            float startY = (float) Math.random() * getResources().getDisplayMetrics().heightPixels;
            float endX = (float) Math.random() * getResources().getDisplayMetrics().widthPixels;
            float endY = (float) Math.random() * getResources().getDisplayMetrics().heightPixels;
            myView.addLine(startX, startY, endX, endY);
            return true;
        }
        return super.onOptionsItemSelected(option_menu);
    }
}

关键修改说明

  • 成员变量声明:将MyView设为Activity成员,解决菜单点击时无法访问自定义View的问题
  • 图形数据持久化:用List<Line>存储所有线条参数,确保每次重绘都能显示全部图形
  • Paint初始化优化:在View构造方法中初始化Paint,避免onDraw重复创建对象影响性能
  • 重绘触发:每次添加新图形后调用invalidate(),通知系统重新绘制View
  • 可扩展设计:自定义Line类存储图形参数,后续添加其他图形(如矩形、圆)时,只需扩展图形类并修改集合类型即可

内容的提问来源于stack exchange,提问作者jlsogorb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 12:43:16