Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Animation Flicker

I've been trawling through as many threads on this topic that I can find on the flicker that arises in Android 2.2 when dealing with AnimationListeners, but I can't quite solve my issue.

What I've got is a LinearLayout 'popover' that the user touches to move down about 100 pixels, and touches again to move it back up. I've finally got it working on the first part without any flicker (thanks to the suggestion to call clearAnimation() on the view being animated), but when doing the opposite (ie, moving the view back up), there's a flicker at the start. I can't really call clearAnimation() in the onAnimationStart() method as it won't animate!

Of course, all animation works perfectly if I used setFillAfter() without any animation listener, but then the view's touch area won't move (because the view itself hasn't "actually" moved).

Any help would be greatly appreciated.

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);
    }

});
like image 668
Jarrod Robins Avatar asked Feb 22 '12 00:02

Jarrod Robins


5 Answers

I had the same problem and after few days I found the solution ... thanx to:

http://www.mail-archive.com/[email protected]/msg67535.html

I figured out a solution to this problem. The clue came from the fact that when showing the view, everything worked fine. Apparently, when the animation is running, the update that would be forced by the show happens in the background and doesn't cause the flicker. Adding a short animation to the back end of the onAnimationEnd() when we are hiding the view makes the flicker go away.

Here is the new onAndimationEnd() in the working code

  public void onAnimationEnd(Animation animation) {
            animation = new TranslateAnimation(0.0f, 0.0f, 0.0f, 0.0f);
            animation.setDuration(1);
            mPlayer0Panel.startAnimation(animation);
   } 
like image 133
Cristi Maris Avatar answered Nov 03 '22 01:11

Cristi Maris


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

This worked for me.

like image 22
stevo.mit Avatar answered Nov 03 '22 03:11

stevo.mit


You shouldn't have to use clearAnimation() on onAnimationEnd().

Try this:

  1. Use setFillBefore(true) and setFillAfter(true) on both animations
  2. Set the correct layout properties when starting and when ending both animations
like image 3
goncalossilva Avatar answered Nov 03 '22 01:11

goncalossilva


I searched for all stackoverflow posts for animation issue (flicker and sluggish). I didnt find any perfect answer. But I have found the solution for the same, which is as below,

onStart of Animation use,

view_you_want_to_animate.setDrawingCacheEnabled(true);

onEnd of Animation use,

view_you_want_to_animate.setDrawingCacheEnabled(false);

Now my view does not have flicker or sluggish behavior when my view is animating. It works well for me.

like image 3
Abhijit Kurane Avatar answered Nov 03 '22 02:11

Abhijit Kurane


I faced the same error, but it only appeared in some views, although all had the same implementation. As it turned out, it happened for two reasons:

  • When I had android:animateLayoutChanges="true" in my root xml element
  • When the problematic view was directly connected to the root xml element

So, two solutions, either remove the android:animateLayoutChanges="true" tag (suggested since you're not using it), or use a wrapper Layout around the problematic view! So instead of:

<?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>

, do

<?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>
like image 3
Orestis Gartaganis Avatar answered Nov 03 '22 01:11

Orestis Gartaganis