安卓动画闪烁问题

17

我一直在浏览关于在Android 2.2中处理AnimationListeners时出现闪烁的尽可能多的主题,但我无法完全解决我的问题。

我有一个LinearLayout 'popover',用户触摸它可以向下移动约100像素,并再次触摸以将其移回。我终于让它在第一部分工作正常(感谢建议,在正在动画的视图上调用clearAnimation()),但在相反的情况下(即将视图移回),开始时会出现闪烁。我不能在onAnimationStart()方法中调用clearAnimation(),因为它不会执行动画!

当然,如果我使用setFillAfter()而没有任何动画监听器,所有动画都能完美地工作,但是触摸区域不会移动(因为视图本身没有“实际”移动)。

非常感谢任何帮助。

this.popoverTab.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        popoverTab.setClickable(false);
        popoverTab.setFocusable(false);
        if (popoverHidden) {
            Log.d(TAG, "About to show popover");
            // the popover is currently hidden, show it.
            TranslateAnimation animation = new TranslateAnimation(0, 0, 100, 0);
            animation.setDuration(700);
            animation.setFillBefore(true);
            animation.setAnimationListener(new AnimationListener() {
                public void onAnimationEnd(Animation animation) {

                }

                public void onAnimationRepeat(Animation animation) {

                }

                public void onAnimationStart(Animation animation) {
                    footer.layout(footer.getLeft(), (footer.getTop() - 100), footer.getRight(), footer.getBottom());
                }
            });
            footer.startAnimation(animation);
        } else {
            Log.d(TAG, "About to hide popover");
            // the popover is showing, hide it.
            TranslateAnimation animation = new TranslateAnimation(0, 0, 0, 100);
            animation.setDuration(700);
            animation.setFillAfter(true);
            animation.setAnimationListener(new AnimationListener() {
                public void onAnimationEnd(Animation animation) {
                    footer.clearAnimation();
                    footer.layout(footer.getLeft(), (footer.getTop() + 100), footer.getRight(), footer.getBottom());
                }

                public void onAnimationRepeat(Animation animation) {

                }

                public void onAnimationStart(Animation animation) {

                }
            });
            footer.startAnimation(animation);
        }
        // invert.
        popoverHidden = !popoverHidden;
        popoverTab.setClickable(true);
        popoverTab.setFocusable(true);
    }

});
6个回答

52

我遇到了同样的问题,几天后找到了解决方案...感谢:

http://www.mail-archive.com/android-developers@googlegroups.com/msg67535.html

我找到了解决这个问题的方法。线索来自于当显示视图时,一切都正常运作。 显然,在动画正在运行时,由show引起的更新在后台发生,并且不会导致闪烁。 当我们隐藏视图时,在onAnimationEnd()的结尾添加一个短动画可以消除闪烁。

这是工作代码中新的onAndimationEnd():

  public void onAnimationEnd(Animation animation) {
            animation = new TranslateAnimation(0.0f, 0.0f, 0.0f, 0.0f);
            animation.setDuration(1);
            mPlayer0Panel.startAnimation(animation);
   } 

非常感谢您解决了这个问题! - Jared Burrows
1
非常感谢。我花了太长时间才找到这个。 - braden
我遇到了闪烁问题(我不知道闪烁和闪烁是否是同一件事),这解决了这种情况。 - Misters
经过长时间的搜索,这个解决方案拯救了我的一天。 - silentsudo
它在我的项目上运行良好,该项目使用Rebound(Facebook)和Backboard(Tumblr)实现浮动操作按钮。 - TyeolRik
非常奇怪,截至今天仍然有效(在Android 4.2.2、4.4、5.0、5.0.1、5.1.1、6.0、6.0.1上测试过)...非常感谢。 - El Don

13
@Override
public void onAnimationEnd(Animation animation)
{
    footer.clearAnimation();
}

这对我有用。


5
我遇到了同样的错误,但只在一些视图中出现,尽管它们都有相同的实现。事实证明,这是由于两个原因造成的:
  • 当我在根xml元素中使用android:animateLayoutChanges="true"
  • 当问题视图直接连接到根xml元素时
因此,有两个解决方案,要么删除android:animateLayoutChanges="true"标签(建议这样做,因为您没有使用它),要么在问题视图周围使用包装布局!所以,改为:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:animateLayoutChanges="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/btnClose"
        android:layout_width="50dp"
        android:layout_height="50dp">

        <ImageView
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_gravity="center"
            android:src="@drawable/ic_arrow_back" />
    </LinearLayout>
...
</RelativeLayout>

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:animateLayoutChanges="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="50dp"
        android:layout_height="50dp">

        <LinearLayout
            android:id="@+id/btnClose"
            android:layout_width="50dp"
            android:layout_height="50dp">

            <ImageView
                android:layout_width="32dp"
                android:layout_height="32dp"
                android:layout_gravity="center"
                android:src="@drawable/ic_arrow_back" />
        </LinearLayout>
    </LinearLayout>
    ...
</RelativeLayout>

1
这个帖子中被低估的答案之一。我的视图在动画后闪烁的原因是因为 android:animateLayoutChanges="true"。我认为它与编程时使用的 Transition 重叠了。移除 android:animateLayoutChanges="true" 解决了我的问题。 - flamyoad

3

我搜索了所有关于动画问题(闪烁和卡顿)的stackoverflow帖子,但没有找到完美的答案。但是我找到了解决方案,如下所示:

在动画的 onStart 中使用以下代码:

view_you_want_to_animate.setDrawingCacheEnabled(true);

在动画结束时使用 onEnd,请参考以下内容:
view_you_want_to_animate.setDrawingCacheEnabled(false);

现在我的视图在动画过程中不再出现闪烁或迟钝的行为。这对我来说效果很好。


这对我也起作用了,无论是独立的 alpha 动画还是 translate + scale 动画集。 - BVB
"setDrawingCacheEnabled"已被弃用。 - Malwinder Singh

3

onAnimationEnd()中不应该使用clearAnimation()

尝试以下:

  1. 两个动画上使用setFillBefore(true)setFillAfter(true)
  2. 在开始和结束两个动画时设置正确的布局属性

当我将面板向上移动时,仍然出现了闪烁问题。我通过在其后面放置一个包含与前面相同内容的虚拟视图来解决了这个问题。 - Jarrod Robins
我遇到了同样的问题,似乎调整view.layout()会导致闪烁。 - Jeroen

0

好的,我曾经遇到过同样的问题并进行了搜索,最终找到了这篇文章。我找到了解决方案,并想分享我的解决方案。

我有许多动画正在运行,但最近开始出现闪烁问题,但当我追踪问题时发现,在 for 循环下绘制动画列表后出现了闪烁问题。(数组列表)

我简单地添加了 try catch 来避免问题,问题是:一些动画在运行时被移除,但没有足够的时间让线程更新,所以循环仍然尝试并失败,但不会显示,而是闪烁,但在数组列表绘制中使用 try 和 catch 解决了我的问题。


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