2

嗨,我正在使用 AnimatorSet 和 ValueAnimator 将多个动画应用于视图。

当用户触摸视图时,连续的动画将应用于视图。当用户在视图上移动手指时,我这样做是为了产生“缩放效果”。

该视图是一个自定义库。

这是动画的代码:

private void createAnim(final View v) {
    animating = true;
    if (D)
        Log.i(TAG, "sarting animation");
    try {
        v.clearAnimation();
        v.getAnimation().reset();
    } catch (Exception e) {

    }
    
    set = new AnimatorSet();
    
    set.addListener(new AnimatorListener() {

        @Override
        public void onAnimationStart(Animator animation) {

            
        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }

        @Override
        public void onAnimationEnd(Animator animation) {
            if (D)
                Log.i(TAG, "Animation ended");
            animating = false;
        }

        @Override
        public void onAnimationCancel(Animator animation) {
            animating = false;
            if (D)
                Log.i(TAG, "Animation cancelled");

        }
    });     

    set.setDuration(100);

    ValueAnimator v1 = ObjectAnimator.ofFloat(v, "scaleX", mScaleFactor);
    ValueAnimator v2 = ObjectAnimator.ofFloat(v, "scaleY", mScaleFactor);

    animationList.add(v1);
    animationList.add(v2);
    set.playTogether(v1, v2);

set.start()
}

我有一个 onTouchListener 并且在动作移动时我连续调用这个方法来增加或减少 mScaleFactor。

当用户松开手指时,我希望视图回到以前的状态,我的意思是删除所有应用的动画,就好像它们从未应用于视图一样。问题是你可以很容易地为一个动画做到这一点,但对于许多这样的动画,我就是找不到正确的方法。这是我尝试过的:

- 将动画添加到 ArrayList 并在每个动画上执行 animation.reverse(),每个动画都添加 +100 的延迟,因此一个接一个地执行,但最终结果似乎与以前不完全相同动画。

v.clearAnimation(); 只取消最后一个动画 v.getAnimation().reset(); 仅适用于最后/活动动画。有没有一种方法可以让视图恢复到任何动画开始之前的状态?非常感谢

4

1 回答 1

5

AnimatorSet仅仅因为没有“reverse”方法,逆转 an 的效果可能会很棘手。在这种情况下,最简单的方法可能只是另一种AnimatorSet与原始方法相反的方法。这里的问题是你AnimatorListener可能不同步。如果您这样做并且想要保留布尔值,那么您必须将其实现为某种信号量。

public static class AnimatorTracker implements AnimatorListener{
    int counter;

    public AnimatorTracker() {
      counter = 0;
    }

    public boolean isAnimating() {
      return counter == 0;
    }

    @Override
    public void onAnimationStart(Animator animation) {
      counter++;
    }

    @Override
    public void onAnimationRepeat(Animator animation) {
    }

    @Override
    public void onAnimationEnd(Animator animation) {
      counter--;
    }

    @Override
    public void onAnimationCancel(Animator animation) {
      // Canceling an animation invokes onAnimationEnd, so nothing needs to be done.
    }
  }

然后按照您刚才的方式制作套装:

AnimatorTracker tracker = new AnimatorTracker(); // or make it a global reference
AnimatorSet set = new AnimatorSet();
AnimatorSet reverseSet = new AnimatorSet();

ValueAnimator v1 = ObjectAnimator.ofFloat(v, "scaleX", mScaleFactor);
ValueAnimator v2 = ObjectAnimator.ofFloat(v, "scaleY", mScaleFactor);
ValueAnimator reverseV1 = ObjectAnimator.ofFloat(v, "scaleX", 1.0f);
ValueAnimator reverseV2 = ObjectAnimator.ofFloat(v, "scaleY", 1.0f);


set.addListener(tracker);
set.setDuration(100);
set.playTogether(v1, v2);

reverseSet.addListener(tracker);
reverseSet.setDuration(100);
reverseSet.playTogether(reverseV1, reverseV2);

set.start()当你想向前动画时调用。reverseSet.start()当你想要动画回来时调用。

于 2012-08-16T12:57:43.927 回答