69

尽管设置为true,onAnimationEnd但触发事件时似乎并未真正完成android动画。animation.hasEnded

我希望我的视图在它的最后改变它的背景可绘制ScaleAnimation,但你可以清楚地看到它在完成前几毫秒发生了变化。问题是,它闪烁是因为新背景出现(=is)缩放了很短的时间,直到动画真正完成。

有没有办法让动画真正结束,或者只是阻止新背景在这么短的时间内缩放?

谢谢!


//编辑:我正在使用 anAnimationListener来获取以下调用:

    @Override
public void onAnimationEnd(Animation animation)
{
    View view = (MyView) ((ExtendedScaleAnimation) animation).getView();

    view.clearAnimation();
    view.requestLayout();
    view.refreshBackground(); // <-- this is where the background gets changed
}
4

12 回答 12

94

这是与此问题相关的实际错误http://code.google.com/p/android-misc-widgets/issues/detail?id=8

这基本上表明当 AnimationListener 附加到 Animation 时 onAnimationEnd 方法不能很好地工作

解决方法是在您将动画应用到的视图中侦听动画事件例如,如果最初您将动画侦听器附加到这样的动画

mAnimation.setAnimationListener(new AnimationListener() {
    @Override
    public void onAnimationEnd(Animation arg0) {
        //Functionality here
    }
});

然后像这样将动画应用于 ImageView

mImageView.startAnimation(mAnimation);

要解决此问题,您现在必须创建自定义 ImageView

public class MyImageView extends ImageView {

然后重写onAnimationEndView 类的方法并提供那里的所有功能

@Override
protected void onAnimationEnd() {
    super.onAnimationEnd();
    //Functionality here
}

这是此问题的正确解决方法,在覆盖的 View -> onAnimationEnd 方法中提供功能,而不是附加到动画的 AnimationListener 的 onAnimationEnd 方法。

这可以正常工作,并且在动画结束时不再有任何闪烁。希望这可以帮助。

于 2011-02-24T21:05:55.510 回答
32

我本来可以通过在onAnimationEnd内的动画视图上调用clearAnimation()来解决这个问题,这消除了闪烁。奇怪的是为什么有人必须这样做,因为只有在动画已经结束时才应该调用 onAnimationEnd 回调。但我想答案在于框架对视图/布局如何处理动画回调的深度。现在把它当作一个无黑客的解决方案,它只是有效的。

        animation.setAnimationListener(new AnimationListener() {

        public void onAnimationEnd(Animation anim) {
            innerView.clearAnimation();   // to get rid of flicker at end of animation

            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams
            (innerBlockContainer.getWidth(), innerBlockContainer.getHeight());

            /* Update lp margin, left/top to update layout after end of Translation */
            ViewGroup parent_ofInnerView = (ViewGroup)innerView.getParent();
            vp.updateViewLayout(innerBlockContainer, lp);

        }

        public void onAnimationRepeat(Animation arg0) {}

        public void onAnimationStart(Animation arg0) {
        }

    });

     innerView.startAnimation(animation);
于 2011-04-12T20:54:42.970 回答
6

我有同样的问题并使用解决了它

view.clearAnimation();

view.startAnimation(anim);
于 2014-09-10T14:15:46.543 回答
6

我遇到了类似的问题,我将 Soham 的解决方案与自定义视图类一起使用。

它工作得很好,但最后,我找到了一个对我有用的更简单的解决方案。

在调用view.StartAnimation(animation), 之后,在我的程序的下一步之前,我添加了一个短暂的延迟,该延迟足以让动画完成,但又足够短,以至于用户不会注意到:

new Handler().postDelayed(new Runnable() {
       @Override
       public void run() {
           nextStepInMyProgram();
       }
     }, 200);// delay in milliseconds (200)
于 2013-09-08T11:58:00.180 回答
2

出于某种原因,onAnimationStart 可以正常工作,而 onAnimationEnd 不能。所以这是我最初的做法以及我所做的更改:

尝试1(闪烁):a)将图像从0px移动到80px b)在onAnimationEnd中,将图像的位置设置为80px

尝试 2(无闪烁): a) 在 onAnimationStart 中,将图像的位置设置为 80px b) 将图像从 -80px 移动到 0px

希望这是有道理的。基本上我改变了我做的方式

于 2011-02-08T19:11:21.197 回答
2

尝试从您的对象中使用 getAnimation() :

public void onShowListBtnClick(View view)
    {
        rightPanel.startAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.slide_left));

        rightPanel.getAnimation().setAnimationListener(new Animation.AnimationListener() {    
            @Override
            public void onAnimationStart(Animation animation) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onAnimationRepeat(Animation animation) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                // write your code here
            }
        });
}
于 2016-06-09T20:19:12.940 回答
1

动画也可以在屏幕旋转时停止。在这种情况下 onAnimationEnd() 没有被调用。我的解决方法:

 animation.setDuration(animationDuration);
 animation.setAnimationListener(new AnimationListenerAdapter() {...});
 view.startAnimation(animation);
 handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if(!animation.hasEnded()) {
                    // here you can handle this case
                }
            }
        }, animationDuration + 100);
于 2015-07-31T09:42:22.653 回答
0

一个简单的解决方法是将一行添加到AnimationListener.onAnimationEnd()

@Override 
public void onAnimationEnd(Animation a) {
    a.setAnimationListener(null);
    …
}
于 2015-06-29T14:18:20.497 回答
0

您也可以使用setUpdateListener, 然后检查动画进度的当前部分并采取相应措施。

这是一个淡出动画的 Kotlin 示例,它最终使视图从布局中消失:

view.animate()
        .alpha(0f)
        .setDuration(duration)
        .setUpdateListener { animation ->
            if (animation.animatedFraction > 0.99f) {
                view.visibility = View.GONE
            }
        }
        .start()
于 2020-09-23T10:04:08.177 回答
0

我遇到了这个问题,因为我Animation没有在主线程中启动。这导致 aduration为 0。但是,Animation确实播放正确 - 它只是onAnimationEnd()在执行后立即调用。

于 2015-09-24T11:53:17.933 回答
0

如果您将重复计数用作无限,则不会调用 onAnimationEnd。检查文档链接

于 2018-03-28T10:19:04.170 回答
-1

这对我有用:

@Override
public void onAnimationUpdate(ValueAnimator animation) {
    if (Float.compare(animation.getAnimatedFraction(),1.0f)) {
    // animation ended;
        //do stuff post animation
    }
}
于 2013-10-30T14:08:56.093 回答