Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: add view with expand animation (without blinking)

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).

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.

For more information see posts like this one and this one.

Here's how I add the view and start the animation:

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

The createExpansion() method:

public static Animation createExpansion(View view) {

    return new SizedHeightScaleAnimation(view, 0, 1,
            Animation.RELATIVE_TO_SELF, 0f,
            Animation.RELATIVE_TO_SELF, 0f);
}

And finally the SizedHeightScaleAnimation animation class:

/**
 * 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();
    }
}

By the way, you can create the collapse effect this way:

public static Animation createCollapse(View view) {

    return new SizedHeightScaleAnimation(view, 1, 0,
            Animation.RELATIVE_TO_SELF, 0f,
            Animation.RELATIVE_TO_SELF, 0f);
}

When you use it you'll probably want to remove the view from its parent when the animation is done:

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);
like image 668
Ferran Maylinch Avatar asked Jan 07 '14 13:01

Ferran Maylinch


People also ask

What is animation in Android and how to use it?

Animation is the process of adding a motion effect to any view, image, or text. With the help of an animation, you can add motion or can change the shape of a specific view. Animation in Android is generally used to give your UI a rich look and feel. The animations are basically of three types as follows: 1. Property Animation

How to start and stop the loading animation in Android?

You have added Android Button with a label Start loading, this button will be used to start and stop the loading animation. 7- Open up MainActivity.java file, inside this file you will initialize and reference rotateloading and btnLoading like this.

How to set interpolator type for animation in Android?

pulse_interpolator: Set interpolator type used for animation. Accepted values are “ Linear “, “ Accelerate “, “ Decelerate “, “ AccelerateDecelerate “ Navigate to the app > res > layout > activity_main.xml and add the below code to that file.

What is property animation in Android?

Property Animation is one of the robust frameworks which allows animating almost everything. This is one of the powerful and flexible animations which was introduced in Android 3.0. Property animation can be used to add any animation in the CheckBox, RadioButtons, and widgets other than any view. Attention reader! Don’t stop learning now.


1 Answers

This might be a little simpler:

public void expand(final View view) {
    view.getLayoutParams().height = 0;

    Animation a = new Animation() {
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t)
        {
            view.getLayoutParams().height = (int)(mTargetHeight * interpolatedTime);
            view.requestLayout();
        }

        @Override
        public boolean willChangeBounds() {
            return true;
        }
    };

    a.setDuration(1000);
    view.startAnimation(a);
}
like image 103
Filipe Silva Avatar answered Oct 08 '22 18:10

Filipe Silva