android 帧动画的动态加载(同步策略)

// 自定义一个animationDrawable,监听动画结束
public abstract class GowildAnimationDrawable extends AnimationDrawable {
    
    Handler finishHandler;      // 判断结束的Handler
    
    public GowildAnimationDrawable(AnimationDrawable animationDrawable) {
        // 这里得自己把每一帧加进去
        for (int i = 0; i < animationDrawable.getNumberOfFrames(); i++) {
            this.addFrame(animationDrawable.getFrame(i), animationDrawable.getDuration(i));
        }
    }
    
    @Override
    public void start() {
        super.start();
        /**
         * 首先用父类的start()
         * 然后启动线程,来调用onAnimationEnd()
         * 单词调用
         */
        finishHandler = new Handler();
        finishHandler.postDelayed(
            new Runnable() {
                public void run() {
                    onAnimationEnd();
                }
            }, getTotalDuration());
    }

    /**
     * @Title: getTotalDuration
     * @Description: TODO(这个方法获得动画的持续时间(之后调用onAnimationEnd()))
     * @param @return    设定文件
     * @return int    返回类型
     * @throws
     */
    public int getTotalDuration() {
        int durationTime = 0;
        for (int i = 0; i < this.getNumberOfFrames(); i++) {
            durationTime += this.getDuration(i);
        }
        return durationTime;
    }
    
    /**
     * @Title: onAnimationEnd
     * @Description: TODO(结束时调用的方法,一定要实现)
     * @param     设定文件
     * @return void    返回类型
     * @throws
     */
    public abstract void onAnimationEnd();
}
// 初始化加载图片帧
public class PetGuideFrameAnimation {

    /**
     * @Fields frameTime : TODO(每一帧的播放时间)
     */
    private static final int frameTime = 1;
    
    private Context mContext = null;
    private Matrix mmMatrix = null;
    private ImageView mImageView = null;
    
    /**
     * @Fields resource : TODO(素材,播放时间)
     */
    private List<Map<Integer, Integer>> resource = new ArrayList<Map<Integer, Integer>>();
    
    private int resourceIndex = 0;
    
    private int randomSeed = 2;
    
    private int currentTime = 0;
    
    private onFrameAnimationListener mFrameAnimationListener = null;
    
    private long startTime = 0L;
    
    /**
     * @Fields perListCount : TODO(每次加载帧动画数)
     */
    private int perListCount = 1; 
    
    /**
     * @Fields listIndex : TODO(帧动画组每组索引)
     */
    private int listIndex = 0;
    
    /**
     * @Fields frameAniming : TODO(动画播放标志)
     */
    private boolean frameAniming = true;
    
    /**
     * @Fields animationTime : TODO(帧动画持续时间)
     */
    private int animationTime = 0;
    
    public PetGuideFrameAnimation(Context context, Matrix matrix, ImageView imageView) {
        mContext = context;
        mmMatrix = matrix;
        mImageView = imageView;
        
        initPetGuide1();
    }
    
    public void setFrameAnimationListener(onFrameAnimationListener frameAnimationListener) {
        this.mFrameAnimationListener = frameAnimationListener;
    }
    
    @SuppressWarnings("deprecation")
    public AnimationDrawable getDrawableGuide() {
        AnimationDrawable frameAnim = new AnimationDrawable();
        animationTime = 0;
        listIndex = 0;
        while (frameAniming && listIndex < perListCount) {
            if (resourceIndex < resource.size()) {
                int id = resource.get(resourceIndex).keySet().iterator().next();
                Bitmap temp = BitmapFactory.decodeResource(mContext.getResources(), id);
                BitmapDrawable guide = new BitmapDrawable(Bitmap.createBitmap(temp, 0, 0, temp.getWidth(), temp.getHeight(),
                        mmMatrix, true));
                
                currentTime = resource.get(resourceIndex).values().iterator().next() * frameTime;
                animationTime += currentTime;
                frameAnim.addFrame(guide, currentTime);
                resourceIndex++;
                listIndex++;
            } else {
                frameAniming = false;
            }
        }
        frameAnim.setOneShot(true);
        return frameAnim;
    }
    
    /**
     * @Title: getFrameAniming
     * @Description: TODO(帧动画加载状态)
     * @param @return    设定文件
     * @return boolean    返回类型
     * @throws
     */
    public boolean getFrameAniming() {
        return frameAniming;
    }
    
    
    @SuppressLint("UseSparseArrays")
    private void initPetGuide1() {
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        map.put(R.drawable.pet_guide_1_01, 12);
        resource.add(map);
        map = new HashMap<Integer, Integer>();
        map.put(R.drawable.pet_guide_1_02, 2);
        resource.add(map);
        map = new HashMap<Integer, Integer>();
        map.put(R.drawable.pet_guide_1_01, 2);
        resource.add(map);
        map = new HashMap<Integer, Integer>();
        map.put(R.drawable.pet_guide_1_02, 2);
        resource.add(map);
        map = new HashMap<Integer, Integer>();
        map.put(R.drawable.pet_guide_1_03, 16);
        resource.add(map);
        map = new HashMap<Integer, Integer>();
        map.put(R.drawable.pet_guide_1_01, 2);
        resource.add(map);
    }
}
    // 调用开始动态加载
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.gowild_pet_guide_window,
                container, false);
        guideImage = (ImageView) root
                .findViewById(R.id.pet_guide_image);        
        
        mPetGuideFrameAnimation = new PetGuideFrameAnimation(mPetMainActivity, null, guideImage);
        finishHandler.post(runable);
        return root;
    }
    
    Handler finishHandler = new Handler();
    
    /**
     * @Fields runable : TODO(帧动画动态加载)
     */
    Runnable runable = new Runnable() {
        
        @Override
        public void run() {
            if (mPetGuideFrameAnimation.getFrameAniming()) {
                mAnimationDrawable = mPetGuideFrameAnimation.getDrawableGuide();
                gowildAnimationDrawable = new GowildAnimationDrawable(mAnimationDrawable) {
                            
                    @Override
                    public void onAnimationEnd() {
                        if (!mPetGuideFrameAnimation.getFrameAniming()) {
                            mPetMainActivity.getFrameAnimationListener().frameAnimationFinish();
                        }
                    }
                };
                guideImage.setBackgroundDrawable(gowildAnimationDrawable);
                gowildAnimationDrawable.start();
                finishHandler.postDelayed(runable, gowildAnimationDrawable==null?0:gowildAnimationDrawable.getTotalDuration());
            } else {
                mPetMainActivity.getFrameAnimationListener().frameAnimationFinish();
            }
        }
    };

主要思路:

通过循环递归将帧动画不断加载出来,避免一次性全部初始化。

存在问题:

大部分时间都耗费在了图片加载上,所以尽管上面有设置每一帧显示时间,但在从第一组到第二组过度的过程中,会出现严重的停机卡顿。如果改一次压缩一次,图片的压缩即使控制在40KB左右,每一次的延迟都会浪费在图片加载上,播放效果也不会非常流畅。

你可能感兴趣的:(动态加载,帧动画)