【问题标题】:How to reset ObjectAnimator to it's initial status?如何将 ObjectAnimator 重置为初始状态?
【发布时间】:2015-02-21 08:44:32
【问题描述】:

我想用 scaleX 和 scaleY 振动视图,我正在使用此代码执行此操作,但问题是有时视图未正确重置,并且显示应用了比例...

我希望当动画结束时,视图必须始终保持其原始状态

这是代码:

                ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 1f, 0.9f);
                scaleX.setDuration(50);
                scaleX.setRepeatCount(5);
                scaleX.setRepeatMode(Animation.REVERSE);
                ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 1f, 0.9f);
                scaleY.setDuration(50);     
                scaleY.setRepeatCount(5);
                scaleY.setRepeatMode(Animation.REVERSE);
                set.play(scaleX).with(scaleY);
                set.start();

谢谢

【问题讨论】:

    标签: android android-animation android-view objectanimator


    【解决方案1】:

    你可以添加一个AnimatorListener,在动画结束时得到通知:

    scaleY.addListener(new AnimatorListener() {
    
                @Override
                public void onAnimationEnd(Animator animation) {
                    // TODO Restore view
    
                }
                @Override
                public void onAnimationStart(Animator animation) {
    
                }
    
                @Override
                public void onAnimationRepeat(Animator animation) {
    
                }
    
    
    
                @Override
                public void onAnimationCancel(Animator animation) {
    
                }
            });
    

    【讨论】:

    • 是的,我知道,但是……我怎样才能恢复视图的原始状态?
    • 你试过用 yourView.clearAnimation() 清除动画吗?
    • 好的,我看到您正在使用 ObjectAnimator。这是一个属性动画。关于属性动画和视图动画之间的区别,这里有一个很好的解释。 stackoverflow.com/questions/11855570/…。您应该尝试创建视图动画,因为它不会影响原始视图
    【解决方案2】:

    对于ValueAnimator和ObjectAnimator可以这样一试:

    animator.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            animation.removeListener(this);
            animation.setDuration(0);
            ((ValueAnimator) animation).reverse();
        }
    });
    

    更新 在 Android 7 上它不起作用。 使用插值器的最佳方式。

    public class ReverseInterpolator implements Interpolator {
    
        private final Interpolator delegate;
    
        public ReverseInterpolator(Interpolator delegate){
            this.delegate = delegate;
        }
    
        public ReverseInterpolator(){
            this(new LinearInterpolator());
        }
    
        @Override
        public float getInterpolation(float input) {
            return 1 - delegate.getInterpolation(input);
        }
    }
    

    在你的代码中

    animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                animation.removeListener(this);
                animation.setDuration(0);
                animation.setInterpolator(new ReverseInterpolator());
                animation.start();
            }
    });
    

    【讨论】:

    • 为什么需要animation.removeListener(this);
    • @DavidChen 因为在.reverse()之后,会再次调用onAnimationEnd()
    • 在我的测试中,这个解决方案产生了无尽的振动,而不是停止它并恢复到原始大小。可能有错误吗?
    【解决方案3】:

    根据文档(Property Animation):

    属性动画系统可以通过更改 View 对象中的实际属性来为屏幕上的 View 设置动画。此外,Views 还会在其属性发生变化时自动调用 invalidate() 方法来刷新屏幕。

    所以您可以使用AnimatorListener 来监听动画事件,然后只需重置您动画的视图属性。假设cancel 事件和scaleX 属性:

    scaleAnimator.setListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationCancel(Animator animation) {
            scaleView.setScaleX(0)
        }
    });
    

    希望这能有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-15
      • 1970-01-01
      • 2020-04-12
      • 2021-09-05
      • 2023-03-17
      • 2020-08-31
      相关资源
      最近更新 更多