我在安卓中使用像“drawCircle”和“drawPoint”这样的canvas函数,效果很好。
但是现在的问题是如何延迟绘制这些不同的图形,以使其看起来像动画。
我应该使用什么样的机制?尝试了异步方式,但我不喜欢它。
我应该使用一种定时器来定时绘制,还是有其他聪明的方法来做到这一点?
我在安卓中使用像“drawCircle”和“drawPoint”这样的canvas函数,效果很好。
但是现在的问题是如何延迟绘制这些不同的图形,以使其看起来像动画。
我应该使用什么样的机制?尝试了异步方式,但我不喜欢它。
我应该使用一种定时器来定时绘制,还是有其他聪明的方法来做到这一点?
我使用这种策略,首先声明一个 Handler 和一个 Runnable:
private final Observable mObservable = new Observable();
private final static int TIME_STEP_MS = 5;
private final Handler mHandler = new Handler();
private final Runnable mTimeManager = new Runnable()
{
public void run()
{
mObservable.notifyObservers(TIME_STEP_MS);
mHandler.postDelayed(mTimeManager, TIME_STEP_MS);
}
};
当我想要启动我的时间管理器时,只需调用mTimeManager.run(),它将开始定期通知已添加的观察者(Observer)。
如果由于某种原因需要停止计时器或其他操作,只需执行以下操作:
mHandler.removeCallbacks(mTimeManager);
[ 编辑 - 更完整的代码 ]
好的,那么让我们更清晰地阐述一下。首先,我创建了一个自定义的可观察对象,就像这样[这是可选的]:
private final Observable mObservable = new Observable()
{
public void notifyObservers()
{
setChanged();
super.notifyObservers();
};
@Override
public void notifyObservers(Object data)
{
setChanged();
super.notifyObservers(data);
};
};
public void resumeDrawing()
{
if (!mTimeManagerRunning) // just a boolean field in my class
{
System.err.println("Resuming renderer."); // just for debug
mTimeManager.run();
mTimeManagerRunning = true;
}
else
{
System.err.println("Renderer already running."); // just for debug
}
}
并且它的对偶:
public void pauseDrawing()
{
if (mTimeManagerRunning)
{
System.err.println("Pausing renderer.");
mHandler.removeCallbacks(mTimeManager);
mTimeManagerRunning = false;
}
else
{
System.err.println("Renderer already paused.");
}
}
好的,现在我们可以启动和停止时间管理器,但是有谁在监听呢?没有人!所以让我们添加它们:在我的渲染器的构造函数中,我向我的mObservable
对象添加了一些Observer
s,其中之一就是渲染器本身,因此我的渲染器扩展了Thread
并实现了Observer
:
@Override // from Observer interface
public void update(Observable arg0, Object arg1)
{
mElapsedMsRedraw += (Integer) arg1;
if (mElapsedMsRedraw >= mDrawingMsPerFrame)
{
mElapsedMsRedraw = 0;
drawEm(); // refresh the canvas and stuff
}
}
mObservable.addObserver(THE_OBJECT - Implements Observer)
。我相信可能有更复杂的方法来实现这个,但是对于我的需求,我使用了一个简单的方法,它有很多优点: 我首先为每个绘图点创建坐标(和任何其他所需数据)的记录,而不是在现场绘制点,然后使用计时器(最好是Android处理程序)进行复制。这也提供了许多实际绘图时的可能性:暂停、加快/减慢速度、倒退等等。 我不知道这种方法是否适用于复杂的绘图,但对于绘制形状、曲线、表面等来说是可以的。