【问题标题】:How to get current canvas?如何获取当前画布?
【发布时间】:2012-02-10 19:41:09
【问题描述】:

我有 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 包含在 Horizo​​ntalScrollView 中。因为如果我在这个 DrawView 中设置正确的坐标,没有人知道可绘制的圆圈在哪里。

【问题讨论】:

  • 这个问题很难理解。请检查它
  • 破译你想要完成的事情并不容易:) 首先,删除canvas2:它不像你想象的那样工作。我怀疑你想保留以前绘制的圆圈,不是吗?如果这是您的目标,您必须维护绘图调用的历史记录,并且可以通过两种方式做到这一点:1)您存储一个数组Point[]并在onDraw中绘制每个圆圈;或 2) 每次添加一个圈子时,您都会更新缓存 Bitmap
  • 我不会画这个圆圈,但不要触摸屏幕!
  • 我意识到了。我写socket-drawer。 Player_1 有 DrawView 并且可以触摸它。 Player_2 有 DrawView 但不能触摸它。 Player_1 为每个服务器设置触摸坐标,Player_2 得到它。这是工作。 Player_1 可以画圆圈,我看到了。 Player_2 正确获取它(套接字连接类将坐标从服务器发送到 DrawView 类,我在 Log (Log.v("pnts.substring", pnts2);) 中看到它)但是我不能在 setPoints 函数中调用 onDraw,因为我从来没有调用/创建/获取它,这是我的问题 - Player_2 看不到 Player_1 的圈子。
  • 当您收到一个新点时,将其添加到 List 并调用 View.postInvalidate()。这将调用您的 onDraw(),您将对其进行修改以循环遍历 List 并为传递给 onDraw 的 Canvas 上的每个点绘制一个圆圈(这是 canvas,而不是 canvas2!)

标签: android view android-canvas


【解决方案1】:

你不能。画布由系统管理并传递给您的onDraw()。我不明白你为什么在外面需要它。像这样重新声明setPoints

public void setPoints(Canvas canvas, Float xP, Float Yp)

您可以保留以前的图纸的缓存(或存储以前的点)

【讨论】:

  • 积分不是问题,我保留。关于“Canvas canvas”:从不调用 onDraw 怎么办?
  • 你似乎不知道Android是如何绘制Views的。当系统检测到一个小部件需要(重新)绘制时,它会敲你的小部件的门,并以onDraw(Canvas) 响应。因此,您可以保证每次需要时都会调用此方法。 trigger the repaint 的一种方法是调用invalidate()(或postInvalidate)。所以你永远不必自己调用 onDraw,但要确保 Android 会在需要时调用它。您需要提供回调。另外,请说明“我想画圆圈但不触摸视图”的含义
  • 能给我链接或关键字吗?
  • 文档很少。 2D drawing guide, View API
【解决方案2】:

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

【讨论】:

  • 问题仅在 Canvas 调用中。
【解决方案3】:

您在onDraw() 中画圈。这就是View 应该工作的方式(从技术上讲,它实际上是在draw() 方法中,但我们会忽略这一点)。在setPoints()中,在类范围内的变量中设置圆的点,调用invalidate(),然后像onDraw()那样画圆。如果您遵循此方法,您将遵循视图设计的类流程。

【讨论】:

  • hmm.. public void setPoints(Float xP, Float Yp) { canvas2.drawCircle(xP, yP, 5, paint);无效(); } 所以呢?
  • 没有。 canvas2.drawCircle(xP, yP, 5, paint); 进入 onDraw()。您保存xPyP 的值,然后在setPoints() 中调用invalidate()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-02
  • 1970-01-01
  • 2012-12-06
  • 2012-06-21
  • 2021-08-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多