AnimationDrawable只能运行一次

时间:2017-12-11 12:12:29

标签: android animation android-windowmanager

我真的需要帮助来修复这个动画。 我使用addFrame()设置动画动态。每个生成的动画由5帧组成。共有5种不同的动画是可能的。动画由处理程序启动 - 每5秒钟一次。

    setAnimation(); //inital setting of animation

    stimulusOverlay.setBackground(animation);

    final Handler recallStimulusHandler = new Handler();
    Runnable runAnimation = new Runnable() {
        @Override
        public void run() {
            stimulusOverlay.setVisibility(View.VISIBLE);
            animation.start();
            setStimulusInvisibleHandler();
            recallStimulusHandler.postDelayed(this, 5000);
        }
    };
    stimulusOverlay.post(runAnimation);

    private void setStimulusInvisibleHandler(){
        final Handler setInvisibleHandler = new Handler();
        final Runnable setStimulusInvisible = new Runnable() {
            @Override
            public void run() {
                stimulusOverlay.setVisibility(View.INVISIBLE);
                 setAnimation();
            }
        };
        setInvisibleHandler.postDelayed(setStimulusInvisible, 2000);
    }

我需要使用Handler。否则,帧将不会在给定时间内显示。 2秒后(动画需要大约1.5秒),我使用函数setAnimation()更改动画 - 用于下一个循环。

    private void setAnimation() {

        Resources res = this.getResources();
        String stimulusString = getStimulusFromPref(countAnimation); // never empty
        int stimulusId = res.getIdentifier(stimulusString, "drawable", this.getPackageName());
        int stimulusLength = stimulusString.length();
        String maskingString = "mask_" + stimulusLength;
        int maskingId = res.getIdentifier(maskingString, "drawable", this.getPackageName());

        AnimationDrawable nextAnimation = new AnimationDrawable();
        nextAnimation.setOneShot(true);
        nextAnimation.addFrame(res.getDrawable(R.drawable.transparent), 300);
        nextAnimation.addFrame(res.getDrawable(maskingId), 300);
        nextAnimation.addFrame(res.getDrawable(stimulusId), 300);
        nextAnimation.addFrame(res.getDrawable(maskingId), 300);
        nextAnimation.addFrame(res.getDrawable(R.drawable.transparent), 300);
        animation = nextAnimation;

        countAnimation = (countAnimation + 1)%5;
    }

该守则第一次运行正常。之后什么也没有出现,没有抛出任何例外或警告。

使用日志:

代码每5秒运行一次

动态图像生成工作正常(对于每种可能的组合)

我还考虑过setAnimation()末尾的递归调用,但我认为每隔5秒调用一次处理程序会使递归无效。 getResources()总是返回相同的值,所以我认为一切都在这里。 我需要用新动画覆盖animation,因为没有可能像removeFrames那样重置动画。 还有一些代码使ImageView可见/不可见,但这也不是问题。 我将ImageView添加到我的windowManager中:(不要认为问题只是为了完整性)

    windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    stimulusOverlay = new ImageView(this);
    stimulusOverlay.setVisibility(View.VISIBLE);

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT
    );

    windowManager.addView(stimulusOverlay, params);

也许你已经知道这里出了什么问题。只是问一些问题或其他问题。

2 个答案:

答案 0 :(得分:0)

显然你只调用一次处理程序。第一次执行处理程序没有被再次调用并且它会停止执行。相反,在循环中再次调用stimulusOverlay。

final Handler recallStimulusHandler = new Handler();
Runnable runAnimation = new Runnable() {
    @Override
    public void run() {
        stimulusOverlay.setVisibility(View.VISIBLE);
        animation.start();
        setStimulusInvisibleHandler();
        recallStimulusHandler.postDelayed(this, 5000);
        //call this handler again
        stimulusOverlay.post(runAnimation);
    }
};
stimulusOverlay.post(runAnimation);

同时删除setStimulusInvisibleHandler()方法中的setInvisibleHandler.postDelayed(setStimulusInvisible, 2000)

答案 1 :(得分:0)

您应该删除setOneShot(true);

setOneShot (布尔oneShot):设置动画播放一次还是重复播放。

详细信息可用here