如何获取当前画布?

16

我有一个DrawView。如果我触摸这个视图,它会画出小圆圈。我想要画圆圈,但不想通过触摸视图来画 - 使用“setPoints”函数帮助。我的做法:

package com.samples;
import ...

public class DrawView extends View {
    ArrayList<Point> points = new ArrayList<Point>();

    Paint paint = new Paint();

    private int pSize = 5;
    private int pColor = Color.BLACK;

    public DrawView(Context context, AttributeSet attrs) {

        super(context, attrs);

        setFocusable(true);
        setFocusableInTouchMode(true);

        this.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                v.setOnTouchListener(this);
                    Point point = new Point();
                    point.x = event.getX();
                    point.y = event.getY();
                    points.add(point); 
                    invalidate();
                }
                return true;
            }
        });
        requestFocus();
    }

    @Override
    public void onDraw(Canvas canvas) { 
        for (Point point : points) {
            canvas.drawCircle(point.x, point.y, pSize, paint);
        }
    }

    public void setPoints(Float xP, Float yP)
    {
        Point point = new Point();
        point.x = xP;
        point.y = yP;
        points.add(point);
        postInvalidate();
    }
}

class Point {
    float x, y;

    @Override
    public String toString() {
        return x + ", " + y;
    }
}
请告诉我,如何从setPoints函数中获取画布? 更新: 哇,这真是一个有趣的问题。我的DrawView包含在HorizontalScrollView中。因为如果我在这个DrawView中设置正确的坐标,就不知道可绘制的圆圈在哪里了。

这个问题很难理解。请仔细检查它。 - Raffaele
很难理解你想要实现什么 :) 首先,删除那个 canvas2:它不像你想象的那样工作。我猜你想保留之前绘制的圆形,是吗?如果这是你的目标,你必须维护绘制调用的历史记录,并可以通过两种方式实现:1)存储一个数组 Point[] 并在 onDraw 中绘制每个圆;或者 2)每次添加圆时更新缓存的 Bitmap - Raffaele
我想画这个圆圈,但不要触摸屏幕! - Leo
我明白了。我写了socket-drawer。Player_1有DrawView并且可以触摸它。Player_2也有DrawView但不能触摸它。Player_1通过服务器设置触摸坐标,而Player_2获取它。这很有效。Player_1可以画圆,我可以看到它。Player_2正确地获取它(Socket连接类将坐标发送到DrawView类的服务器,我在日志中看到它(Log.v("pnts.substring", pnts2);))。但是,由于我从未调用/创建/获取它,因此我无法在setPoints函数中调用onDraw,这是我的问题-Player_2看不到Player_1的圆。 - Leo
当你收到一个新的Point时,将其添加到List<Point>中并调用View.postInvalidate()。这将调用你的onDraw()方法,你需要修改它来循环遍历List<Point>并在传递给onDraw()的Canvas上为每个Point绘制一个圆(注意是canvas而不是canvas2!)。 - Raffaele
显示剩余3条评论
3个回答

9
你做不到。画布由系统管理,并传递给你的onDraw()。我不明白为什么你需要在那之外使用它。只需要像这样重新声明setPoints即可。
public void setPoints(Canvas canvas, Float xP, Float Yp)

你可以保留之前的绘图缓存(或存储之前的点)。

点数不是问题,我会保留它。关于“画布画布”:如果从未调用onDraw,我该怎么办? - Leo
2
您似乎不知道如何在Android中绘制视图。当系统检测到小部件需要重新绘制时,它会敲打您的小部件的门,通过 onDraw(Canvas) 响应。因此,您可以确保每次需要时都会调用此方法。一种触发重绘的方法是通过调用 invalidate()(或 postInvalidate)。因此,您永远不必自己调用 onDraw,但请确保Android在需要时会调用它。您需要提供回调。另外,请说明您所说的“我想画圆形但不想触摸视图”是什么意思。 - Raffaele
你能给我一个链接或关键词吗? - Leo
文档很少。2D绘图指南View API - Raffaele

1
尝试在DrawView类中将canvas2声明为公共变量。

问题只出现在Canvas调用中。 - Leo

1

你可以在onDraw()方法中绘制圆形。这是View的工作方式(严格来说,实际上是在draw()方法中,但我们可以忽略这一点)。在setPoints()方法中,将圆的点设置为类范围内的变量,调用invalidate()方法,然后在onDraw()方法中以此方式绘制圆形。如果你遵循这种方法,就是按照视图设计的类流程进行操作。


嗯...public void setPoints(Float xP, Float Yp) { canvas2.drawCircle(xP, yP, 5, paint); invalidate(); } 那么呢? - Leo
No. canvas2.drawCircle(xP, yP, 5, paint); 放在 onDraw() 中。你保存 xPyP 的值,然后在 setPoints() 中调用 invalidate() - DeeV

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接