title: Android: add view with expand animation (without blinking)
body: <p>I want to add a view to a view group using an expanding animation, so the added view starts very small and takes more and more space until it reaches its full size (probably moving other views in the process).</p>
  
  <p>After trying different approaches I came up with the solution below. Vote if it helps you or please post a better alternative. I am sure there must be an easier way to do this.</p>
  
  <p>For more information see posts like <a href="https://stackoverflow.com/questions/8063466/how-to-expand-a-layout-height-with-animation">this one</a> and <a href="https://stackoverflow.com/questions/4946295/android-expand-collapse-animation/5122460#5122460">this one</a>.</p>
  
  <p>Here's how I add the view and start the animation:</p>
  
  <pre><code>// Trick: set height to 1 so the view doesn't take its full size at the beginning.
  // (0 doesn't work, I don't know why)
  container.addView(view, LayoutParams.MATCH_PARENT, 1);
  Animation expansion = createExpansion(view);
  expansion.setDuration(200);
  view.startAnimation(expansion);
  </code></pre>
  
  <p>The <code>createExpansion()</code> method:</p>
  
  <pre><code>public static Animation createExpansion(View view) {
  
      return new SizedHeightScaleAnimation(view, 0, 1,
              Animation.RELATIVE_TO_SELF, 0f,
              Animation.RELATIVE_TO_SELF, 0f);
  }
  </code></pre>
  
  <p>And finally the <code>SizedHeightScaleAnimation</code> animation class:</p>
  
  <pre><code>/**
   * Like {@link ScaleAnimation} for height scaling that also resizes the view accordingly,
   * so it takes the right amount of space while scaling.
   */
  public class SizedHeightScaleAnimation extends ScaleAnimation {
  
      private float fromHeight;
      private float toHeight;
      private View viewToScale;
  
      public SizedHeightScaleAnimation(View viewToScale, float fromY, float toY) {
          super(1, 1, fromY, toY);
          init(viewToScale, fromY, toY);
      }
  
      public SizedHeightScaleAnimation(View viewToScale, float fromY, float toY, float pivotX, float pivotY) {
          super(1, 1, fromY, toY, pivotX, pivotY);
          init(viewToScale, fromY, toY);
      }
  
      public SizedHeightScaleAnimation(View viewToScale, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {
          super(1, 1, fromY, toY, pivotXType, pivotXValue, pivotYType, pivotYValue);
          init(viewToScale, fromY, toY);
      }
  
      private void init(View viewToScale, float fromY, float toY) {
  
          this.viewToScale = viewToScale;
          viewToScale.measure(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
          fromHeight = viewToScale.getMeasuredHeight() * fromY;
          toHeight = viewToScale.getMeasuredHeight() * toY;
      }
  
      @Override
      protected void applyTransformation(float interpolatedTime, Transformation t) {
          super.applyTransformation(interpolatedTime, t);
  
          final int newHeight = (int) (fromHeight * (1 - interpolatedTime) + toHeight * interpolatedTime);
  
          viewToScale.getLayoutParams().height = newHeight;
          viewToScale.requestLayout();
      }
  }
  </code></pre>
  
  <p>By the way, you can create the collapse effect this way:</p>
  
  <pre><code>public static Animation createCollapse(View view) {
  
      return new SizedHeightScaleAnimation(view, 1, 0,
              Animation.RELATIVE_TO_SELF, 0f,
              Animation.RELATIVE_TO_SELF, 0f);
  }
  </code></pre>
  
  <p>When you use it you'll probably want to remove the view from its parent when the animation is done:</p>
  
  <pre><code>Animation collapse = createCollapse(view);
  collapse.setDuration(200);
  
  collapse.setAnimationListener(new AnimationListener() {
      @Override
      public void onAnimationEnd(Animation animation) {
          final ViewGroup parent = (ViewGroup) view.getParent();
          parent.removeView(view);
      }
  
      ... other overrides ...
  });
  
  view.startAnimation(collapse);
  </code></pre>