I use functions for canvas like drawCircle and drawPoint in android. This works fine.
But the problem now is to draw these different items with a delay, so it looks like an animation.
What kind of mechanism should I use? Have tried with async but I dont like that way of doing it.
Should I use some kind of timer that just draw with an interval or is there other clever ways to do this?
I use this strategy, first I declare a Handler and a Runnable that way:
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);
}
};
Then when I want to start my time manager I just call the mTimeManager.run() and it will start to notify my Observer
s (previously added) periodically.
If you need for some reason stop the timer or something you just do that:
mHandler.removeCallbacks(mTimeManager);
[ EDIT - More complete code ]
Ok than let's make it clearer, first I made a custom Observable object like that [that's optional]:
private final Observable mObservable = new Observable()
{
public void notifyObservers()
{
setChanged();
super.notifyObservers();
};
@Override
public void notifyObservers(Object data)
{
setChanged();
super.notifyObservers(data);
};
};
the reason for that is just because I can't call setChanged() outside Observable class - it's protected, if it's not changed it doesn't notify any observer.
The other declarations keep the same as shown before, now I need to start this TimeManager
somewhere, my app is a LiveWallpaper and I make all rendering stuff into a class that extends a Thread
but you don't need that necessarily, I made a method called resumeDrawing()
, this one is called right after super.start();
at my @Override
of public synchronized void start()
from Thread
class, the method looks like that:
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
}
}
and it's dual:
public void pauseDrawing()
{
if (mTimeManagerRunning)
{
System.err.println("Pausing renderer.");
mHandler.removeCallbacks(mTimeManager);
mTimeManagerRunning = false;
}
else
{
System.err.println("Renderer already paused.");
}
}
Ok, now we can start and stop the time manager, but who's listening? Nobody! so let's add'em: On the constructor of my Renderer I add some Observer
s to my mObservable
object, one of those is the Renderer itself, so my renderer extends Thread
and implements 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
}
}
to add observers you simply do mObservable.addObserver(THE_OBJECT - Implements Observer)
you can see that I don't re-render my stuff each time I'm notified, that's because I use this TimeManager for other thinks than just refresh the Canvas
like updating the position of the objects I want to draw just internally.
So, what you need to slow down the drawing is to change the way your objects change internally while the time passes, I mean your circles and points etc, or you can chance your time step, I recommend the first one.
Was it clearer? I hope it helps.
I would use a timer, or create Animations. You can create Animations that will do all sorts of things including changing transparency over time.
Here's the Android Documentation for Animation Resources
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With