2011-03-28 91 views
0

我正在编写我的第一个android应用程序。所以我仍然处于学习阶段。安卓图形绘制在画布上问题

它非常简单,我在屏幕中心的onDraw()中绘制图形,并且onTouch事件必须将图形移动到用户触摸的位置。为此,onTouch事件将启动一个线程并更新图形。问题是canvas.draw()在从onDraw()调用时工作,但在线程内调用时不会更新画布/屏幕。

我的功能drawSplash(Canvas c,Location l);

我在onDraw()和线程中都调用了相同的函数。

我可以看到的代码唯一的区别是我传递给我的Canvas对象放在我的类的变量的onDraw()函数中,以便我可以再次在线程中使用它。这不知何故感觉不对。如果是这样,那么执行此操作的正确方法是什么?我可以随时获得Canvas对象吗?我怎么做?

  • P

回答

1

你必须.invalidate()与拥有的onDraw方法overrited你的看法。每次调用它时都应该在正确的位置绘制图形。

你应该调用Main Thread中的.invalidate()方法。

+0

啊。所以当我调用invalidate()时,整个视图被破坏了吗?我必须每次都重新绘制整个图形才能更新飞溅? – user220201 2011-03-28 14:52:42

+0

当你调用invalidate()时,画布被清除,并调用'onDraw'方法。所以'onDraw'应该每次绘制所有内容 – 2011-03-28 15:05:36

+0

@iuliux - 这很有趣。以前从未想过它。所以,如果我正在创建一个国际象棋棋盘,那么随着一举一动我再次绘制整个棋盘?这是它通常如何工作?有没有更新图形或至少分离我想更新的东西的概念,同时保持底座(如板在这里)不变? – user220201 2011-03-28 15:38:31

1

这是一个稍微不同的方法。

做一些像这样的全局字段:

private int mX; 
    private int mY; 

,然后在你的onTouch()方法(使用相同的View类的onTouch吧?)你改变这些字段,然后调用invalidate()方法:

public boolean onTouch (View v, MotionEvent event) { 
     mX = event.getX(); 
     mY = event.getY(); 
     invalidate(); 
    } 

所以,现在,该onDraw()方法只会提醒你飞溅的位置(MX,MY)。

+1

好的。为什么我必须首先使视图无效?我不清楚这一点。 invalidate()抹去画布右边?如果是这样,我在onTouch事件还是draw()中调用它会有什么关系?他们明显地被一个接一个地调用。 – user220201 2011-03-28 15:40:51

+0

那么,'invalidate()'方法告诉'View'它显示的内容已经过时。然后,视图通过重绘来自我更新。我不确定以下情况是否属实,但如果每次调用'onDraw'而不是'invalidate()',则会再次绘制飞溅,而不是移动。你最终会在屏幕上产生大量重叠的飞溅 – 2011-03-29 15:47:33

0

在我的理解中,您可以将底板设置为背景图像。

如果你这样做,你不必经常重绘它,但我不是100%肯定的。

看一看Lunar Lander的代码在Android开发人员的视线位置:

http://developer.android.com/resources/samples/LunarLander/index.html

菲尔

+0

这将是一个好方法。但还有很多我想保持不变的其他东西,比如用户的名字和其他真实的东西。我会再次看这个代码。 – user220201 2011-03-28 16:13:46