Каков предпочтительный метод для отображения больших предварительно отрендеренных анимаций в Android? - PullRequest
1 голос
/ 21 декабря 2011

У меня есть серия покадровых анимаций, которые должны быть включены в программу (3 анимации по 200-300 кадров каждая). Как лучше всего отобразить их в Android SDK? Я попытался использовать списки анимации, но они, похоже, хотят одновременно буферизовать все изображения, что приводит к нехватке памяти на устройстве.

1 Ответ

1 голос
/ 22 декабря 2011

У меня возникла точно такая же проблема.
В данный момент я играю анимацию с моим пользовательским классом, производным от 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");

    }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...