The following is a demonstration of how to dynamically animate Android views. This technique requires you to provide the starting width or height, and the ending width or height. If you are working with a view directly these properties should be readily accessible. I invested a substantial amount of time searching for a solution for this. I found this solution to work best.
Since I am animating several views in my project I created a new class. The new class is a subclass of Animation and overrides the applyTransformation() and willChangeBounds() methods. This class is robust enough to animate various views by width, height using a defined animation speed.
// Subclass of Android's android.view.animation.Animation class MyAnimator extends Animation { // Used to define the type of animation upon construction public enum Type { WIDTH, HEIGHT } // The view to be animated private View view; // The dimensions and animation values (this is stored so other changes to layout don't interfere) private final int fromDimension; // Dimension to animate from private int toDimension; // Dimension to animate to private Type type; // See enum above, the type of animation // Constructor public MyAnimator(View view, int toDimension, Type type, long duration) { // Setup references // the view to animate this.view = view; // Get the current starting point of the animation (the current width or height of the provided view) this.fromDimension = type == Type.WIDTH ? view.getLayoutParams().width : view.getLayoutParams().height; // Dimension to animate to this.toDimension = toDimension; // See enum above, the type of animation this.type = type; // Set the duration of the animation this.setDuration(duration); } @Override public void applyTransformation(float interpolatedTime, Transformation t) { // Used to apply the animation to the view final int curPos = fromDimension + (int) ((toDimension - fromDimension) * interpolatedTime); // Animate given the height or width switch (type) { case WIDTH: view.getLayoutParams().width = curPos; break; case HEIGHT: view.getLayoutParams().height = curPos; break; } // Ensure the view is measured appropriately view.requestLayout(); } } |
This demonstration presumes you have an instance of the view you wish to animate. Once you have an instance of the MyAnimator class, you can apply it to a view as follows:
View viewToAnimate; // Reference to the view to animate. int ANIMATION_SPEED = 250; // Should be defined static and final with class fields //Construct an instance of MyAnimator - This one will be used for width animation MyAnimator myAnimator = new MyAnimator(viewToAnimate, targetWidth, MyAnimator.Type.WIDTH, ANIMATION_SPEED); viewToAnimate.startAnimation(myAnimator); |
You can also assign callbacks to the animation by using an instance of Animation.AnimationListener, which fires on animation start, animation finish, and on animation repeat. If desired, attach an instance of AnimationListener as follows:
myAnimator.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) {} @Override public void onAnimationEnd(Animation animation) {} @Override public void onAnimationRepeat(Animation animation) {} }); |