I have created a class that extends SurfaceView in order to cycle a series of ARGB bitmaps. This mostly works, except that the state of the underlying bitmap is (usually, but not always) preserved for each new frame.
In other words, if the first frame I display is opaque, and subsequent frames are transparent, then the opaque pixels from the original frame are not cleared out when the new frames are drawn.
This behavior confuses me, because the documentation for SurfaceHolder.lockCanvas() specifically states:
"The content of the Surface is never preserved between unlockCanvas() and lockCanvas(), for this reason, every pixel within the Surface area must be written."
If I just had a solid background, then calling canvas.drawARGB(255,0,0,0) succeeds to clear it to black...but I want to have a transparent background, and I can't clear it to a transparent color, because canvas.drawARGB(0,0,0,0) has no effect.
import java.util.ArrayList;
import java.util.Random;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
/*
* Accepts a sequence of Bitmap buffers and cycles through them.
*/
class AnimatedBufferView extends SurfaceView implements Runnable
{
Thread thread = null;
SurfaceHolder surfaceHolder;
volatile boolean running = false;
ArrayList<Bitmap> frames;
int curIndex = 0;
public AnimatedBufferView(ArrayList<Bitmap> _frames, Context context)
{
super(context);
surfaceHolder = getHolder();
frames = _frames;
}
public void onResume(){
running = true;
thread = new Thread(this);
thread.start();
}
public void onPause(){
boolean retry = true;
running = false;
while(retry){
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void run()
{
// TODO Auto-generated method stub
while(running)
{
if(surfaceHolder.getSurface().isValid())
{
Canvas canvas = surfaceHolder.lockCanvas();
//clear the buffer?
//canvas.drawARGB(255, 0, 0, 0);
//display the saved frame-buffer..
Matrix identity = new Matrix();
Bitmap frame = frames.get(curIndex);
canvas.drawBitmap(frame, identity, null);
surfaceHolder.unlockCanvasAndPost(canvas);
curIndex = (curIndex + 1) % frames.size();
try {
thread.sleep( 100 );
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}