动画直到UI更新或触摸事件后才开始。

31

我遇到了一个与AlphaAnimation有关的奇怪问题。当调用一个AsyncTask处理程序时,它应该重复运行。

然而,在Activity中第一次调用处理程序时,除非我触摸屏幕或更新UI(例如按下手机菜单按钮),否则动画不会启动。

奇怪的是,一旦动画至少运行了一次,则在再次调用处理程序时,它将毫无问题地开始。

以下是代码示例:

// AsyncTask handler
public void onNetworkEvent()
{
  this.runOnUiThread(new Runnable() {
    @Override
    public void run()
    {
      flashScreen(Animation.INFINITE);
    }
  });
}

// Called method
private void flashScreen(int repeatCount)
{
  final View flashView = this.findViewById(R.id.mainMenuFlashView);

  AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
  alphaAnimation.setRepeatCount(repeatCount);
  alphaAnimation.setRepeatMode(Animation.RESTART);
  alphaAnimation.setDuration(300);
  alphaAnimation.setInterpolator(new DecelerateInterpolator());
  alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
    @Override
    public void onAnimationStart(Animation animation)
    {
      flashView.setVisibility(View.VISIBLE);
    }

    @Override
    public void onAnimationEnd(Animation animation)
    {
      flashView.setVisibility(View.GONE);
    }

    @Override
    public void onAnimationRepeat(Animation animation) { }
  });

  flashView.startAnimation(alphaAnimation);
}

我注意到使用runOnUIThread不是必需的(如果我不使用它,将得到相同的结果),但我喜欢保留它,因为我不在UI线程上。

有什么想法是什么原因导致这种情况?


代码太少,无法理解你的调用顺序。你能发布一下在 Asynctask 执行周围部分的代码吗?另外,你尝试记录相关方法的输入来查看发生了什么了吗? - ilomambo
尝试将动画延迟几秒钟,以便第一次运行。这可能是在视图准备好之前尝试运行动画的情况。 - Sagar Waghmare
5个回答

52

我进一步调查后发现我的问题和这个问题是一样的: Layout animation not working on first run

flashView的可见性默认设置为GONE(导致Animation不能立即开始,因为View从未被渲染),所以我只需要在调用flashView.startAnimation()之前将其设置为INVISIBLE


1
谢谢,使它不可见帮了我大忙。 - Vasanth

30

如果将 View 设置为 VISIBLE 没有效果,就像我遇到的情况一样,那么在开始 Animation 之前调用 requestLayout() 对我很有帮助,像下面这样:

如果将 View设置成VISIBLE无效,在我的情况下,我发现在开始Animation之前调用requestLayout()可以起到帮助作用, 像这样:

Animation an = new Animation() {
...   
view.requestLayout();
view.startAnimation(an);
在我的情况下,我的View的高度是0dip,这阻止了onAnimationStart的调用,这帮助我解决了这个问题。

4
在某些版本的Android上,如果视图的高度或宽度初始值为0dip,则它甚至无法工作。在我的一个案例中,我不得不将初始值设为1dip,但由于边距,该视图并不可见。这样做有所帮助,使动画可以在所有版本上正常工作。 - Oknesif

4
这对我有用:

这对我有用:

view.setVisibility(View.VISIBLE);
view.startAnimation(animation);

我需要将 view 设为 VISIBLE(不是 INVISIBLEGONE),这样才能使视图渲染并实现动画效果。


0

也许这会对某些人有所帮助,因为之前的答案并没有帮到我。

我的动画是在点击时更改视图的高度(从0到实际高度再返回),以展开和折叠的方式进行动画。

直到我添加了监听器并在动画结束时将可见性设置为GONE,才使一切正常运作:

collapseAnim.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationEnd(Animation animation) {
            view.setVisibility(View.GONE);
        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    });

而当展开时,先在动画前将其设置为可见:

 view.setVisibility(View.VISIBLE);
 view.startAnimation(expandAnim);

0

这不是一个容易的问题。在你得到真正的答案之前:动画开始是由onNetworkEvent触发的。由于我们不知道代码的其余部分,你应该去那里看看,尝试将onNetworkEvent更改为另一个你可以轻松识别的事件,以便调试是否代码的其余部分正常或者只是触发器有问题。


1
我可以轻松地触发事件,并且它正在工作。调试显示,直到我第一次与UI交互之前,AnimationListener的onAnimationStart不会被调用。 - Jukurrpa
@Jukurrpa 这个问题是适用于所有 Android 版本还是某些特定版本? - Kai
@Kai 我只有4.1和4.2的设备来测试,而且两个设备都出现了这个问题。 - Jukurrpa
所以 onAnimationStart 没有被调用... 也许你可以尝试将 flashView.startAnimation(alphaAnimation); 直接放在 public void run 方法中,在 flashScreen(Animation.INFINITE); 之后。 - TheBeps

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