为动画加载大图像序列的有效方法

时间:2015-11-30 11:23:24

标签: android-animation android-drawable xml-drawable

我有4个图像序列(png格式),我需要用于我的动画。每个序列大约50帧长,每帧大约300x300,所以我有30 MB的资源加载。加载它们以避免内存泄漏的最有效方法是什么?我应该选择xml可绘制动画还是有更好的方法?

我不需要同时在屏幕上显示所有这些内容。将仅显示一次动画。

1 个答案:

答案 0 :(得分:0)

非常感谢。 我遇到了同样的问题,看了你的答案一段时间后我通过覆盖一个AnimationDrawable来解决它。 因此,如果您遇到的问题是无法加载阵列中的所有图像,因为它太大而无法容纳内存,请在需要时加载图像。 我的AnimationDrawable是这样的:

public abstract class MyAnimationDrawable extends AnimationDrawable {

    private Context context;
    private int current;
    private int reqWidth;
    private int reqHeight;
    private int totalTime;

    public MyAnimationDrawable(Context context, int reqWidth, int reqHeight) {
        this.context = context;
        this.current = 0;
        //In my case size of screen to scale Drawable
        this.reqWidth = reqWidth;
        this.reqHeight = reqHeight;
        this.totalTime = 0;
    }

    @Override
    public void addFrame(Drawable frame, int duration) {
        super.addFrame(frame, duration);
        totalTime += duration;
    }

    @Override
    public void start() {
        super.start();
        new Handler().postDelayed(new Runnable() {

            public void run() {
                onAnimationFinish();
            }
        }, totalTime);
    }

    public int getTotalTime() {
        return totalTime;
    }

    @Override
    public void draw(Canvas canvas) {
        try {
            //Loading image from assets, you could make it from resources 
            Bitmap bmp = BitmapFactory.decodeStream(context.getAssets().open("presentation/intro_000"+(current < 10 ? "0"+current : current)+".jpg"));
            //Scaling image to fitCenter
            Matrix m = new Matrix();
            m.setRectToRect(new RectF(0, 0, bmp.getWidth(), bmp.getHeight()), new RectF(0, 0, reqWidth, reqHeight), Matrix.ScaleToFit.CENTER);
            bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), m, true);
            //Calculating the start 'x' and 'y' to paint the Bitmap 
            int x = (reqWidth - bmp.getWidth()) / 2;
            int y = (reqHeight - bmp.getHeight()) / 2;
            //Painting Bitmap in canvas
            canvas.drawBitmap(bmp, x, y, null);
            //Jump to next item
            current++;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    abstract void onAnimationFinish();

}

现在要播放动画,你需要做下一步

    //Get your ImageView
    View image = MainActivity.this.findViewById(R.id.presentation);

    //Create AnimationDrawable
    final AnimationDrawable animation = new MyAnimationDrawable(this, displayMetrics.widthPixels, displayMetrics.heightPixels) {

        @Override
        void onAnimationFinish() {
            //Do something when finish animation
        }

    };
    animation.setOneShot(true); //dont repeat animation
    //This is just to say that my AnimationDrawable has 72 frames with 50 milliseconds interval
    try {
        //Always load same bitmap, anyway you load the right one in draw() method in MyAnimationDrawable
        Bitmap bmp = BitmapFactory.decodeStream(MainActivity.this.getAssets().open("presentation/intro_00000.jpg"));
        for (int i = 0; i < 72; i++) {
            animation.addFrame(new BitmapDrawable(getResources(), bmp), 50);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    //Set AnimationDrawable to ImageView
    if (Build.VERSION.SDK_INT < 16) {
        image.setBackgroundDrawable(animation);
    } else {
        image.setBackground(animation);
    }

    //Start animation
    image.post(new Runnable() {

        @Override
        public void run() {
            animation.start();
        }

    });

这就是全部,并且工作正常我!

相关问题