Most efficient way to show frame by frame animation android

前端 未结 8 1697
醉话见心
醉话见心 2021-02-01 07:41

I am trying to show frame by frame animation by changing images in a imageview. I tried animation drawable in xml and also changing the bitmap of the imageview inside a Handler.

相关标签:
8条回答
  • 2021-02-01 07:54

    Maybe stupid answer but it may help you. Make the animation using another tool and save it as a high quality video and then just play the video.

    0 讨论(0)
  • 2021-02-01 07:55

    Try exporting your images to a GIF? Android does support decoding GIF files.

    Have a look : Supported Media Formats.

    0 讨论(0)
  • 2021-02-01 07:57

    Loading the bitmaps from assets instead of resources saved 40% decoding time for me. You might want to try that.

    So this went from 5 seconds with resources to 3 seconds on your pictures on my 2012 Nexus 7:

    long time = System.currentTimeMillis();
    try {
        for (int i = 0; i < 35; i++) {
            InputStream assetStream = getAssets().open(
                    "_step" + (i + 1) + ".png");
            try {
                Bitmap bitmap = BitmapFactory.decodeStream(assetStream);
                if (bitmap == null) {
                    throw new RuntimeException("Could not load bitmap");
                }
                mBitmaps.add(bitmap);
            } finally {
                assetStream.close();
            }
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    Log.d("ANIM", "Loading bitmaps elapsed "+(System.currentTimeMillis() - time)+"ms");
    
    0 讨论(0)
  • 2021-02-01 08:00

    Create an imageView using programming and then rotate it with an angle and then make another one and then rotate it.. do it for number of imageView you want to show. you only have to add only one image for it. you can rotate an image like this..

    Matrix matrix=new Matrix();
    imageView.setScaleType(ScaleType.MATRIX);   //required
    matrix.postRotate((float) angle, pivX, pivY);
    imageView.setImageMatrix(matrix);
    
    0 讨论(0)
  • 2021-02-01 08:03

    Try using an AnimationDrawable for your ImageView. See my answer here for example.

    0 讨论(0)
  • 2021-02-01 08:06

    I'm facing the same problem and I have solved it by overriding an AnimationDrawable. So, if the problem is you that can't load all images in array because it is too big for the memory to hold it, then load the image when you need it. My AnimationDrawable is this:

    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();
    
    }
    

    Now to play animation you need to do what next

        //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();
            }
    
        });
    

    That is all, and works OK form me!!!

    0 讨论(0)
提交回复
热议问题