【问题标题】:Sprite Image Animation精灵图像动画
【发布时间】:2018-01-13 20:54:53
【问题描述】:

我试图找到在我的 android 项目上为 sprite 图像设置动画的简单方法。找到了一些复杂的解决方案,在 RecyclerViewAdapter 上使用它们并不是那么容易。为什么它不能简单地使用自定义视图。

这是一个以动画形式显示的示例精灵图像。 https://cdn.codeandweb.com/blog/2016/05/10/how-to-create-a-sprite-sheet/spritestrip.png

【问题讨论】:

    标签: android imageview android-animation android-imageview android-custom-view


    【解决方案1】:

    这个自定义视图非常适合 sprite emoji 图像。

    如果有人在 Android 上需要精灵图像动画,可以使用这个自定义 ImageView。

    public class AnimatedImageView extends AppCompatImageView {
    
        private static final String KEY_ACTIVITY = "activity";
        private static final String KEY_FRAME_COUNT = "frameCount";
        private static final String KEY_FRAME_SPEED = "frameSpeed";
        private static final String KEY_LOOP_ENABLE = "loopEnable";
        private static final String KEY_SOURCE_URL = "sourceUrl";
    
        private AppCompatActivity activity;
    
        private Bitmap sourceBitmap;
        private Bitmap croppedBitmap;
    
        private int xPos;
    
        private int frameCount;
        private int frameSpeed;
        private int frameWidth, frameHeight;
    
        private int sourceWidth;
    
        private boolean loopEnable;
    
        private Timer timer;
    
        public AnimatedImageView(Context context) {
            super(context);
        }
    
        public AnimatedImageView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
        }
    
        public AnimatedImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        public void start(Map <String,Object> map) {
            this.activity = (AppCompatActivity) map.get(KEY_ACTIVITY);
            this.frameCount = (int) map.get(KEY_FRAME_COUNT);
            this.frameSpeed = (int) map.get(KEY_FRAME_SPEED);
            this.loopEnable = (boolean) map.get(KEY_LOOP_ENABLE);
            new DownloadImage().execute(String.valueOf(map.get(KEY_SOURCE_URL)));
        }
    
        private void animateBitmap() {
            timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    prepareBitmap();
                }
            }, 0, frameSpeed);
        }
    
        private void prepareBitmap() {
            croppedBitmap = Bitmap.createBitmap(sourceBitmap, xPos, 0, frameWidth, frameHeight);
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    setImageBitmap(croppedBitmap);
    
                    if (xPos + frameWidth >= sourceWidth) {
                        if (loopEnable) {
                            xPos = 0;
                        } else {
                            xPos = 0;
                            timer.cancel();
                            return;
                        }
                    }
    
                    xPos = xPos + frameWidth;
                }
            });
        }
    
        private void buildView(Bitmap bitmap) {
            sourceBitmap = bitmap;
            frameWidth = sourceBitmap.getWidth() / frameCount;
            frameHeight = sourceBitmap.getHeight();
            sourceWidth = sourceBitmap.getWidth();
    
            measure(frameWidth, frameHeight);
    
            animateBitmap();
        }
    
        public int getFrameCount() {
            return frameCount;
        }
    
        public void setFrameCount(int frameCount) {
            this.frameCount = frameCount;
        }
    
        public int getFrameSpeed() {
            return frameSpeed;
        }
    
        public void setFrameSpeed(int frameSpeed) {
            this.frameSpeed = frameSpeed;
        }
    
        public boolean isLoopEnable() {
            return loopEnable;
        }
    
        public void setLoopEnable(boolean loopEnable) {
            this.loopEnable = loopEnable;
        }
    
        private class DownloadImage extends AsyncTask<String, Void, Bitmap> {
            @Override
            protected Bitmap doInBackground(String... url) {
                String imageURL = url[0];
                Bitmap bitmap = null;
    
                try {
                    InputStream input = new URL(imageURL).openStream();
                    bitmap = BitmapFactory.decodeStream(input);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return bitmap;
            }
    
            @Override
            protected void onPostExecute(Bitmap bitmap) {
                buildView(bitmap);
            }
        }
    
        public static class AnimationBuilder {
    
            private final int DEFAULT_FRAME_COUNT = 20;
            private final int DEFAULT_FRAME_SPEED = 40;
    
            private AppCompatActivity activity;
            private int frameCount = DEFAULT_FRAME_COUNT;
            private int frameSpeed = DEFAULT_FRAME_SPEED;
            private boolean loopEnable;
            private String sourceUrl = "";
    
            private AppCompatActivity getAppCompatActivity() {
                return activity;
            }
    
            public AnimationBuilder from(AppCompatActivity activity) {
                this.activity = activity;
                return this;
            }
    
            private int getFrameCount() {
                return frameCount;
            }
    
            public AnimationBuilder frameCount(int frameCount) {
                this.frameCount = frameCount;
                return this;
            }
    
            private int getFrameSpeed() {
                return frameSpeed;
            }
    
            public AnimationBuilder frameSpeed(int frameSpeed) {
                this.frameSpeed = frameSpeed;
                return this;
            }
    
            private boolean isLoopEnable() {
                return loopEnable;
            }
    
            public AnimationBuilder loopEnable(boolean loopEnable) {
                this.loopEnable = loopEnable;
                return this;
            }
    
            private String getSourceUrl() {
                return sourceUrl;
            }
    
            public AnimationBuilder load(String sourceUrl) {
                this.sourceUrl = sourceUrl;
                return this;
            }
    
            public Map<String, Object> build() {
                Map<String, Object> builtMap = new HashMap<>();
                builtMap.put(KEY_ACTIVITY, getAppCompatActivity());
                builtMap.put(KEY_FRAME_COUNT, getFrameCount());
                builtMap.put(KEY_FRAME_SPEED, getFrameSpeed());
                builtMap.put(KEY_LOOP_ENABLE, isLoopEnable());
                builtMap.put(KEY_SOURCE_URL, getSourceUrl());
                return builtMap;
            }
        }
    }
    

    用法:

    要使用此自定义 ImageView,您需要知道 frameCount。

    仅适用于图片网址。

    问题帧数为 6 个图像

    yourAnimatedImageView.start(new AnimatedImageView.AnimationBuilder()
                .from(activity)
                .frameCount(6)
                .frameSpeed(50)
                .load("https://cdn.codeandweb.com/blog/2016/05/10/how-to-create-a-sprite-sheet/spritestrip.png")
                .loopEnable(false).build());
    

    希望它会帮助谁正在寻找在 Android 上动画精灵图像的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-01
      • 2010-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多