title: Android bringToFront causes flicker
body: <p>I am animating three views that are stacked on top of each other. When I tap one that is not the front view, one or two views will slide up or down to uncover the tapped view, bring the tapped view to front, and then return everything to their original position. Most of these work fine. Only when I bring a view to front that I just animated away I get a noticeable flicker.</p>
  
  <p>I have read at least a hundred posts but none contains the solution.
  I am posting this to consolidate every suggested solution in one place and to hopefully find a solution.</p>
  
  <p>I know that the animation does not animate the view itself, but just an image. The view stays at its original position. It is definitely related to that. It only happens when bringing a view to front that just moved.</p>
  
  <p>Moving the view to the animation end position before starting the animation or after the animation is finished does not help one bit.</p>
  
  <p>It also is not related to the <code>AnimationListener.onAnimationEnd</code> bug, since I derived my own views and intercept <code>onAnimationEnd</code> there.</p>
  
  <p>I am using <code>Animation.setFillAfter</code> and <code>Animation.setFillEnabled</code> to keep the final image at the animation end location.</p>
  
  <p>I tried using <code>Animation.setZAdjustment</code> but that one only works for entire screens, not views within a screen.</p>
  
  <p>From what I have learned I suspect that the problem is <code>bringToFront()</code> itself, which does a <code>removeChild()/addChild()</code> on the parent view. Maybe the <code>removeChild</code> causes the redraw showing the view without the removed child briefly.</p>
  
  <p><strong>So my questions:</strong> Does anyone see anything I missed that could fix this?
  Does <em>Android</em> maybe have a command to temporarily stop drawing and resume drawing later. Something like a <code>setUpdateScreen(false) / setUpdateScreen(true)</code> pair?
  That would allow me to skip the <em>flicker</em> stage.</p>
  
  <p>Minimal code to demo the effect follows. Tap white to see red move up and back down behind white without <em>flicker</em> (white comes to front but does not move). Then tap red to see red move back up from behind white and the flicker when it is brought to front just before it slides back down over white. Weird thing is that the same thing does not always happen when using blue instead of red.</p>
  
  <p><em><strong>MainActivity.java</em></strong></p>
  
  <pre><code>package com.example.testapp;
  
  import com.example.testapp.ImagePanel.AnimationEndListener;
  import android.app.Activity;
  import android.os.Bundle;
  import android.view.View;
  import android.view.animation.TranslateAnimation;
  
  public class MainActivity extends Activity
  {
    private static final int ANIMATION_TIME = 1000;
  
    private ImagePanel mRed;
    private ImagePanel mWhite;
    private ImagePanel mBlue;
    private int mFrontPanelId;
  
    private void animate(final ImagePanel panel, final int yFrom, final int yTo,
        final AnimationEndListener animationListener)
    {
      final TranslateAnimation anim = new TranslateAnimation(0, 0, 0, 0, 0, yFrom, 0, yTo);
      anim.setDuration(ANIMATION_TIME);
      anim.setFillAfter(true);
      anim.setFillEnabled(true);
      if (animationListener != null)
      {
        panel.setAnimListener(animationListener);
      }
      panel.startAnimation(anim);
    }
  
    public void onClick(final View v)
    {
      final int panelId = v.getId();
      if (mFrontPanelId == panelId)
      {
        return;
      }
      final ImagePanel panel = (ImagePanel) v;
  
      final int yTop = mWhite.getTop() - mRed.getBottom();
      final int yBot = mWhite.getBottom() - mBlue.getTop();
  
      final boolean moveRed = panelId == R.id.red || mFrontPanelId == R.id.red;
      final boolean moveBlue = panelId == R.id.blue || mFrontPanelId == R.id.blue;
  
      animate(mBlue, 0, moveBlue ? yBot : 0, null);
      animate(mRed, 0, moveRed ? yTop : 0, new AnimationEndListener()
      {
        public void onBegin()
        {
        }
  
        public void onEnd()
        {
          // make sure middle panel always stays visible
          if (moveRed &amp;&amp; moveBlue)
          {
            mWhite.bringToFront();
          }
  
          panel.bringToFront();
  
          animate(mBlue, moveBlue ? yBot : 0, 0, null);
          animate(mRed, moveRed ? yTop : 0, 0, new AnimationEndListener()
          {
            public void onBegin()
            {
            }
  
            public void onEnd()
            {
            }
          });
  
          mFrontPanelId = panelId;
        }
      });
    }
  
    @Override
    public void onCreate(final Bundle savedInstanceState)
    {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
  
      mRed = (ImagePanel) findViewById(R.id.red);
      mWhite = (ImagePanel) findViewById(R.id.white);
      mBlue = (ImagePanel) findViewById(R.id.blue);
      mFrontPanelId = R.id.red;
    }
  }
  </code></pre>
  
  <p><em><strong>ImagePanel.java</em></strong></p>
  
  <pre><code>package com.example.testapp;
  
  import android.content.Context;
  import android.util.AttributeSet;
  import android.widget.ImageView;
  
  public class ImagePanel extends ImageView
  {
    public interface AnimationEndListener
    {
      public void onBegin();
  
      public void onEnd();
    }
  
    private AnimationEndListener mAnim = null;
  
    public ImagePanel(final Context context)
    {
      super(context);
    }
  
    public ImagePanel(final Context context, final AttributeSet attrs)
    {
      super(context, attrs);
    }
  
    public ImagePanel(final Context context, final AttributeSet attrs, final int defStyle)
    {
      super(context, attrs, defStyle);
    }
  
    @Override
    protected void onAnimationEnd()
    {
      super.onAnimationEnd();
      clearAnimation();
      if (mAnim != null)
      {
        final AnimationEndListener anim = mAnim;
        mAnim = null;
        anim.onEnd();
      }
    }
  
    @Override
    protected void onAnimationStart()
    {
      super.onAnimationStart();
      if (mAnim != null)
      {
        mAnim.onBegin();
      }
    }
  
    public void setAnimListener(final AnimationEndListener anim)
    {
      mAnim = anim;
    }
  }
  </code></pre>
  
  <p><strong>activity_main.xml</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:id="@+id/main"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent" &gt;
  
      &lt;com.example.testapp.ImagePanel
          android:id="@+id/blue"
          android:layout_width="300dp"
          android:layout_height="300dp"
          android:layout_alignParentBottom="true"
          android:layout_centerHorizontal="true"
          android:background="#000080"
          android:src="@drawable/testpattern"
          android:onClick="onClick" /&gt;
  
      &lt;com.example.testapp.ImagePanel
          android:id="@+id/white"
          android:layout_width="300dp"
          android:layout_height="300dp"
          android:layout_centerHorizontal="true"
          android:layout_centerVertical="true"
          android:background="#808080"
          android:src="@drawable/testpattern"
          android:onClick="onClick" /&gt;
  
      &lt;com.example.testapp.ImagePanel
          android:id="@+id/red"
          android:layout_width="300dp"
          android:layout_height="300dp"
          android:layout_alignParentTop="true"
          android:layout_centerHorizontal="true"
          android:adjustViewBounds="true"
          android:background="#800000"
          android:src="@drawable/testpattern"
          android:onClick="onClick" /&gt;
  
  &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p><em><strong>testpattern.xml</em></strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;shape xmlns:android="http://schemas.android.com/apk/res/android"
      android:shape="oval" &gt;
  
      &lt;gradient
  
          android:startColor="#00000000"
          android:endColor="#ffffffff" /&gt;
  
  &lt;/shape&gt;
  </code></pre>