У меня возникла точно такая же проблема.
В данный момент я играю анимацию с моим пользовательским классом, производным от ImageView в методе onDraw. Я считываю одно изображение из папки ресурсов и каждый раз назначаю это изображение холсту.Я проверяю, истекло ли определенное время (60 мс в моем случае), и решаю, нужно ли мне показывать новое изображение в конце, я вызываю postInvalidate (), чтобы снова вызывать onDraw.Этот метод отлично работает на моем HTC Desire, но у меня нет возможности протестировать устройства с более низкими характеристиками.
Если никто не предлагает лучшего решения, я не могу опубликовать свой код, чтобы другие могли его прокомментировать.
РЕДАКТИРОВАТЬ:
public class AnimationView extends ImageView
{
private static final String TAG = "AnimView";
//public fields
public String STRING_FORMAT_FOR_PADDING = "%04d";
private String FILE_TYPE = "png";
public boolean STOP_AT_LAST_FRAME = true;
public int DELAY = 60; //delay between frames in milliseconds
//private fields
private boolean mIsPlaying = false;
private boolean mStartPlaying = false;
private Context mContext = null;
private int play_frame = 0;
private long last_tick = 0;
private Bitmap curentFrame = null;
private String dir;
private String prefix;
private int numberOfFrames;
private AnimationViewAnimFinished finishListener;
public AnimationView(Context context, AttributeSet attrs)
{
super(context, attrs);
mContext = context;
}
public void setUpAnimation(String dir, String prefix, int numberOfFrames)
{
this.dir = dir;
this.prefix = prefix;
this.numberOfFrames = numberOfFrames;
curentFrame = loadImage(1); //set first frame of animation to curent frame
}
public void setAnimationFinishListener(AnimationViewAnimFinished finishListener)
{
this.finishListener = finishListener;
}
@Override
protected void onDraw(Canvas c)
{
//Log.d(TAG, "onDraw called");
if (mStartPlaying)
{
Log.d(TAG, "starting animation...");
play_frame = 1;
mStartPlaying = false;
mIsPlaying = true;
c.drawBitmap(curentFrame, 0, 0, null); // blink fix
postInvalidate();
}
else if (mIsPlaying)
{
if (play_frame >= numberOfFrames)
{
mIsPlaying = false;
if (STOP_AT_LAST_FRAME)
{
c.drawBitmap(curentFrame, 0, 0, null);
}
if (finishListener != null)
finishListener.animationFinished(); //finish callback called
}
else
{
long time = (System.currentTimeMillis() - last_tick);
int draw_x = 0;
int draw_y = 0;
if (time >= DELAY) //the delay time has passed. set next frame
{
Log.d(TAG, "drawing frame number:"+play_frame+" signature:"+curentFrame.toString());
last_tick = System.currentTimeMillis();
play_frame++;
curentFrame = loadImage(play_frame);
}
c.drawBitmap(curentFrame, draw_x, draw_y, null);
postInvalidate();
}
}
else //before animation starts ... drawing first frame
{
c.drawBitmap(curentFrame, 0, 0, null);
}
}
private Bitmap loadImage(int numFrame)
{
long startOne = android.os.SystemClock.uptimeMillis();
String name =dir+ prefix + String.format(STRING_FORMAT_FOR_PADDING, numFrame)+"."+FILE_TYPE;
InputStream ins = null;
try {
ins = mContext.getAssets().open(name);
} catch (IOException e) {
e.printStackTrace();
}
Bitmap d = BitmapFactory.decodeStream(ins);
long endOne = android.os.SystemClock.uptimeMillis();
Log.d(TAG,name+" frame decoded in: "+String.valueOf(endOne-startOne)+" ms");
return d;
}
//set flag for starting animation to true and inicicate redraw
public void playAnimation()
{
Log.d(TAG,"Play animation + invalidate()");
mStartPlaying = true;
postInvalidate();
}
//callack class for method restaurants
public static abstract class AnimationViewAnimFinished{
public abstract void animationFinished();
}
}
В методе действий onCreate у меня есть это:
animationHolder = (AnimationView)findViewById(R.id.imageViewAnimationHolderService);
animationHolder.setUpAnimation("animation1/", "frame_", 212);
animationHolder.setAnimationFinishListener(myAnimationFinishListener);
В активах у меня есть папка "animation1" в этомпапка У меня есть 212 .png изображений с именем (frame_0001.png, frame_0002.png, frame_0003.png,…, frame_0212.png)
Когда я начинаю анимацию, я вызываю:
animationHolder.playAnimation();
А это код для слушателя анимации:
AnimationViewAnimFinished myAnimationFinishListener = new AnimationViewAnimFinished() {
@Override
public void animationFinished() {
Log.d(TAG,"animation finished");
}
};