ValueAnimator只重复一次

20

我正在尝试让一个 ValueAnimator 在结束后重复执行。我在 ListView 中使用它与一个 SeekBar 配合使用。奇怪的是,ValueAnimator 会完成,触发 onAnimationEnd() 然后再次开始,但当它到达结尾时,onAnimationEnd() 不会第二次被调用。

    @Override
    public View getContentView(int position, View convertView, ViewGroup parent) {
        ...
        setupTimerBar(t);
        ...
    }


    private AnimatorListenerAdapter generateNewAnimatorListenerAdapter(final TylersContainer t) {
        return new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                setupTimerBar(t);
            }
        };
    }

    private void setupTimerBar(TylersContainer t)
    {       
        View view = t.getView();
        BusTime arrivalTime = t.getBusTime();
        int minutes = BusTime.differenceInMiuntes(arrivalTime, BusTime.now());
        long milliseconds = minutes * 60 * 1000;

        final TimerBar seekBar = (TimerBar) view.findViewById(R.id.SeekBar);

        int progress = Utility.setProgress(arrivalTime, seekBar.getMax());  
        long duration = Utility.setAnimationDuration(progress);

        seekBar.setProgress(progress);
        seekBar.setAnimationDuration(duration);
        seekBar.setAnimationStartDelay(milliseconds);
        seekBar.setAnimatorListenerAdapter(generateNewAnimatorListenerAdapter(t));
    }

seekBar对象实际上是一个自定义对象,其中包含一个SeekBar和一个ValueAnimator,以下是相关部分:

    //Constructor
    public TimerBar(Context context) {
        super(context);

        startTime = Calendar.getInstance();
        valueAnimator = ValueAnimator.ofInt(0, getMax());

        //Override the update to set this object progress to the animation's value
        valueAnimator.addUpdateListener(new AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {    
                int animProgress = (Integer) animation.getAnimatedValue();
                setProgress(animProgress);

            }
         });
    }

    //Specify the start time by passing a long, representing the delay in milliseconds
    public void setAnimationStartDelay(long milliseconds){

        //Set the delay (if need be) and start the counter
        if(milliseconds > 0)
            valueAnimator.setStartDelay(milliseconds);

        valueAnimator.setIntValues(this.getProgress(), this.getMax());

        valueAnimator.start();
    }


    //Set the duration of the animation
    public void setAnimationDuration(long duration){
        valueAnimator.setDuration(duration);
    }


    public void setAnimatorListenerAdapter(AnimatorListenerAdapter ala){
        valueAnimator.addListener(ala);
    }

我不明白为什么它不能重复超过两次。

我尝试使用 Repeat 属性并将其设置为 INFINITE,但这也没有帮助。


编辑:明确一下,我想要的是一个无限重复的动画,每次持续时间都不同。


一些问题:TylersContainer是什么?为什么每次执行setupTimerBar时都要添加新的监听器,却从未删除任何监听器?为什么在setAnimationStartDelay之后调用setAnimatorListenerAdapter?你如何验证onAnimationEnd只被调用了一次? - dst
TylersContainer 是一个对象,它包含一个视图和下一班公交车到达时间(显示在该视图中)。我每次都添加了一个新的监听器,因为这是我找到的示例中的做法,而且我也不知道你需要删除监听器,我以为它们只会在完成后被删除。setAnimationListenerAdaptersetAnimationStartDelay 的顺序是微不足道的。我通过一些打印语句来记录 onAnimationEnd 只被调用了一次。 - Tyler
“setAnimationListenerAdapter和setAnimationStartDelay的顺序是微不足道的。”我问了一下,因为我不确定在添加侦听器之前是否可能会调用onAnimationEnd。通常,您可以尝试使用Android的调试功能逐步执行代码的执行。也许这会产生结果? - dst
谢谢提供的线索,我会去做的。 - Tyler
正如@dst所指出的,我猜您需要重新安排setAnimationStartDelay()setAnimatorListenerAdapter()的顺序,如果持续时间和启动延迟为0,您将会遇到麻烦。 - M-Wajeeh
@TylerAndFriends,你有没有检查我的回答?有什么评论吗? - Khaled.K
2个回答

26

我犯了一个错误,将RepeatMode设置为无限,但这并没有起作用,必须将其设置为RepeatCount

valueAnimator.setRepeatCount(ValueAnimator.INFINITE);

1
如果您正在使用 Animator 并将其与 Animator.AnimatorListener 绑定,则应使用函数 AnimatorListener.onAnimationEnd(),该函数仅在您的动画重复有限次时调用一次。

如果您的动画重复多次,则应改用函数 AnimatorListener.onAnimationRepeat(),每次在动画重复结束后都会调用此函数。

据我所了解,您需要使用 onAnimationRepeat()。因此,如果您只需将要在每次重复后执行的代码从 onAnimationEnd() 移动到 onAnimationRepeat(),这应该就可以解决问题。

参考资料:http://developer.android.com/reference/android/animation/Animator.AnimatorListener.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接