51

I couldn't find a good example for how to do this.

I have a RelativeLayout set with x height.

I want to add a button which expands the height to x+y height.

can someone refer me to a good example on how to do it programmatically?

piojo
  • 1,919
  • 4
  • 24
  • 40

5 Answers5

74

You marked the solution that was closest. This is the exact solution. I had the same problem. Hopefully this answer will help others.

InstantiateResizeAnimation

ResizeAnimation resizeAnimation = new ResizeAnimation(
     view, 
     targetHeight, 
     startHeight
); 
resizeAnimation.setDuration(duration); 
view.startAnimation(resizeAnimation);

ResizeAnimation class should look like this

public class ResizeAnimation extends Animation {
    final int targetHeight;
    View view;
    int startHeight;

    public ResizeAnimation(View view, int targetHeight, int startHeight) {
        this.view = view;
        this.targetHeight = targetHeight;
        this.startHeight = startHeight;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        int newHeight = (int) (startHeight + targetHeight * interpolatedTime);
        //to support decent animation, change new heigt as Nico S. recommended in comments
        //int newHeight = (int) (startHeight+(targetHeight - startHeight) * interpolatedTime);
        view.getLayoutParams().height = newHeight;
        view.requestLayout();
    }

    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
    }

    @Override
    public boolean willChangeBounds() {
        return true;
    }
}
longi
  • 11,104
  • 10
  • 55
  • 89
the_prole
  • 8,275
  • 16
  • 78
  • 163
17

You need a scale animation here is the official documentation

this is in code

private void animate() {
    ImageView imageView = (ImageView) findViewById(R.id.ImageView01);
    ScaleAnimation scale = new ScaleAnimation((float)1.0, (float)1.5, (float)1.0, (float)1.5);
    scale.setFillAfter(true);
    scale.setDuration(500);
    imageView.startAnimation(scale); 
}
digiwebguy
  • 460
  • 1
  • 8
  • 20
Lukap
  • 31,523
  • 64
  • 157
  • 244
  • scaling? i thought I needed translating. i'm adjusting the LayoutParams, are you sure I need scaling? – piojo Nov 09 '11 at 10:32
  • 3
    If you want to increase the size you need scaling. If you only want to move things you need translation. – Janusz Nov 09 '11 at 10:53
  • alright, but I need a scale animation that gets starting height and ending height, and not how much to scale – piojo Nov 09 '11 at 11:08
  • 2
    well if you have 100dip or 100px and you put scale factor of 1 it will make the view 100dip / 100px – Lukap Nov 09 '11 at 12:12
16

Please check below new edited answer as below. But here you need to know the exact new height.

public class LayoutAnimationActivity extends Activity {
    RelativeLayout ril1;
    Button btn;
    int initialHeight;
    int actualHeight;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main2);
        ril1 = (RelativeLayout) findViewById(R.id.relativeLayout1);
        btn = new Button(this);
        btn.setWidth(100);
        btn.setHeight(200);
        btn.setText("Button");
        actualHeight = 210;
        Ani a = new Ani();
        a.setDuration(2000);
        ril1.startAnimation(a);
    }

    class Ani extends Animation {
        public Ani() {}

        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            int newHeight;

            newHeight = (int) (initialHeight * interpolatedTime);

            ril1.removeAllViews();
            btn.setWidth(100);
            btn.setHeight(300);
            btn.setText("as");
            ril1.addView(btn);             
            ril1.getLayoutParams().height = newHeight;
            ril1.requestLayout();
        }

        @Override
        public void initialize(int width, int height, int parentWidth, int parentHeight) {
            super.initialize(width, height, parentWidth, parentHeight);
            initialHeight = actualHeight;
        }

        @Override
        public boolean willChangeBounds() {
            return true;
        }
    };
}
Lii
  • 11,553
  • 8
  • 64
  • 88
Maneesh
  • 6,098
  • 5
  • 36
  • 55
  • well it expands the layout (I did some changes) but there is no animation – piojo Nov 09 '11 at 10:53
  • 1
    I don't understand whats the button got to do with all of this. why you removeAllView and the set new width, height and text to the button. this code only expands the layout, how do I collapse it? – piojo Nov 09 '11 at 13:17
  • 1
    you were the closest. I found this [answer](http://stackoverflow.com/questions/4946295/android-expand-collapse-animation/5122460#5122460) which helped: – piojo Nov 09 '11 at 15:57
  • 8
    public class layout_animation extends Activity - you are code style serial killer – Anton Kizema Mar 15 '16 at 11:51
  • 1
    it works for expansion but to collapse it is not working – avez raj Nov 30 '17 at 10:33
6

Two simple ways to do this without an Animation class:

1) Set android:animateLayoutChanges="true" in you xml layout file

2) Use a ViewProperty animator

layout.setPivot(0);
layout.animate().scaleY(scaleFactor).setDuration(500);

The pivot tells the view where to scale from, default is in the middle, which in my experience is almost never what you want. The duration is optional (default = 1000).

GLee
  • 5,003
  • 5
  • 35
  • 39
2
final Button button1 = (Button) view.findViewById(R.id.button);
    final CollapseAnimator animator = new CollapseAnimator(topLayout);

    final ViewTreeObserver.OnGlobalLayoutListener listener = new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            int mHeight = button1.getMeasuredHeight();
            KLog.i("onGlobalLayout() mHeight:" + mHeight);
            animator.setValues(mHeight*2, mHeight);

        }
    };
    button1.getViewTreeObserver().addOnGlobalLayoutListener(listener);
    button1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            view.post(new Runnable() {
                @Override
                public void run() {
                    button1.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
                    animator.collapse();

                }
            });

        }
    });

and class

public class CollapseAnimator {
    private View view;
    private boolean collapse=true;
    private int duation=300;
    private int destHeight=300;
    private ValueAnimator animator;
    private int originHeight=0;
    private int from=0;
    private int to=0;


    public CollapseAnimator(View view ) {
        this.view = view;
    }

    public void setValues(int destHeight,int originHeight){
        this.destHeight = destHeight;
        this.originHeight=originHeight;
        from=originHeight;
        to=originHeight;
    }
    public void collapse(){


        from=to;
        if(collapse){

            to=destHeight;
            collapse=false;
        }else{
            to=originHeight;
            collapse=true;
        }
        KLog.i("from:" + from+",to:"+to);
        animator = ValueAnimator.ofInt(from, to);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int val = (Integer) valueAnimator.getAnimatedValue();
                ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
                layoutParams.height = val;
                view.setLayoutParams(layoutParams);
            }
        });
        animator.setDuration(duation);
        animator.start();
    }
}
weston
  • 54,145
  • 21
  • 145
  • 203
adsl99801
  • 21
  • 1