I have a canvas and I wish to change the bitmap image every 50 milliseconds.
Basically what I'm trying to do is like a gif animation.
As you can see there's 4 images and every 50 milliseconds I want it to change the image.
the code below doesn't work and I have no clue why.
protected void onDraw(final Canvas canvas) {
res = getResources();
image = BitmapFactory.decodeResource(res, R.drawable.image_1);
canvas.drawBitmap(image, 0, 0, paint);
new Thread(new Runnable() {
@Override
public void run() {
while (!Thread.interrupted())
try {
Thread.sleep(50);
System.out.println("OK2");
time++;
((Activity) context).runOnUiThread(new Runnable() {
@Override
public void run() {
if (time == 1) {
image = BitmapFactory.decodeResource(res,
R.drawable.image_1);
canvas.drawBitmap(image, 0, 0, paint);
invalidate();
}
if (time == 2) {
image = BitmapFactory.decodeResource(res,
R.drawable.image_2);
canvas.drawBitmap(image, 0, 0, paint);
invalidate();
}
if (time == 3) {
image = BitmapFactory.decodeResource(res,
R.drawable.image_3);
canvas.drawBitmap(image, 0, 0, paint);
invalidate();
}
if (time >= 4) {
time = 0;
image = BitmapFactory.decodeResource(res,
R.drawable.image_4);
canvas.drawBitmap(image, 0, 0, paint);
invalidate();
}
}
});
} catch (InterruptedException e) {
}
}
}).start();
super.onDraw(canvas);
}
Thanks in advance.
There's a couple of problems:
You are decoding the resources over and over each time. decodeResource might not be fast enough to load the image within 50 milliseconds. It would be faster to decode the frames once and store them in an array. e.g.:
Bitmap images[4];
void loadFrames()
{
res = getResources();
images[0] = BitmapFactory.decodeResource(res, R.drawable.image_1);
images[1] = BitmapFactory.decodeResource(res, R.drawable.image_2);
images[2] = BitmapFactory.decodeResource(res, R.drawable.image_3);
images[3] = BitmapFactory.decodeResource(res, R.drawable.image_4);
}
You are starting a new thread every time onDraw() is called, which means hundreds of threads will be created. Instead, you should create the thread just once. Inside the thread, increment your counter and set image to the correct frame, then call invalidate:
Thread.sleep(50);
time = (time + 1) % 4;
image = images[time];
((Activity) context).runOnUiThread(new Runnable() {
@Override
public void run() {
invalidate();
}
};
Then inside onDraw(), draw onto the canvas with the current image:
canvas.drawBitmap(image, 0, 0, paint);
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