47

I want to resize some layouts in my Activity.

Here is the code of the main XML:

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/top"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="1"
        android:background="#3ee3e3" >
    </LinearLayout>

    <LinearLayout
        android:id="@+id/middle"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1">
    </LinearLayout>

    <LinearLayout
        android:id="@+id/bottom"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="1"
        android:background="#fe51e6" >
    </LinearLayout>
</LinearLayout>

As you can see, the top and bottom layouts height's is 0, and the middle layout covers all the place.

I want to programmatically decrease the middle layout size, while increase both the top and the bottom layout sizes, till all the layouts have the same height.

I want it to be look like an animation.

How should I do that?

Thanks

Cœur
  • 32,421
  • 21
  • 173
  • 232
dor506
  • 4,466
  • 7
  • 37
  • 67

3 Answers3

101

I wrote a ResizeAnimation for a similar purpose. It's simple but costly.

Java

    /**
     * an animation for resizing the view.
     */
    public class ResizeAnimation extends Animation {
        private View mView;
        private float mToHeight;
        private float mFromHeight;

        private float mToWidth;
        private float mFromWidth;

        public ResizeAnimation(View v, float fromWidth, float fromHeight, float toWidth, float toHeight) {
            mToHeight = toHeight;
            mToWidth = toWidth;
            mFromHeight = fromHeight;
            mFromWidth = fromWidth;
            mView = v;
            setDuration(300);
        }

        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            float height =
                    (mToHeight - mFromHeight) * interpolatedTime + mFromHeight;
            float width = (mToWidth - mFromWidth) * interpolatedTime + mFromWidth;
            LayoutParams p = mView.getLayoutParams();
            p.height = (int) height;
            p.width = (int) width;
            mView.requestLayout();
        }
    }

Kotlin

class ResizeAnimation(
    private val view: View,
    private val toHeight: Float,
    private val fromHeight: Float,
    private val toWidth: Float,
    private val fromWidth: Float,
    duration: Long
) : Animation() {

    init {
        this.duration = duration
    }

    override fun applyTransformation(
        interpolatedTime: Float,
        t: Transformation?
    ) {
        val height = (toHeight - fromHeight) * interpolatedTime + fromHeight
        val width = (toWidth - fromWidth) * interpolatedTime + fromWidth
        val layoutParams = view.layoutParams
        layoutParams.height = height.toInt()
        layoutParams.width = width.toInt()
        view.requestLayout()
    }
}
Tom Howard
  • 3,876
  • 1
  • 35
  • 43
faylon
  • 7,192
  • 1
  • 28
  • 28
  • 1
    I guess you need to override `public void initialize` & `public boolean willChangeBounds` too. – Saba Jamalian Jun 13 '14 at 17:03
  • @faylon Why did you said it's costly? Does it consume more memory or takes more time to execute? – Nitesh Kumar Mar 12 '15 at 20:24
  • 1
    @NiteshKhatri It cost a great deal of cpu, so the animation won't be too smooth on a phone with low-end phones, especially when the layout itself is already complex. I thought we already have better way to implement such animations in new android SDK. – faylon Mar 17 '15 at 07:17
  • @faylon I a supporting 2.3 (API 9) and above. Is there any other more efficient way to implement this animation? I would appreciate that. – Nitesh Kumar Mar 18 '15 at 10:47
  • @NiteshKhatri I haven't been working on Android for the past two years, and don't have time to look deeper into this problem currently. Sorry about that. – faylon Mar 20 '15 at 04:06
  • Who is t ? and how can I make him ? – Marian Pavel Apr 25 '15 at 08:19
  • Strange, but a view size hasn't changed. @Sufian, thanks for the link. – CoolMind Apr 30 '19 at 14:44
4

On Honeycomb (Android 3.0) there is the Animator and ObjectAnimator classes for smoother animations.

Read it here

Example on how to animate the move of a view group (LinearLayout) with a bounce interpolator.

BounceInterpolator bounceInterpolator = new BounceInterpolator();   
ObjectAnimator anim = ObjectAnimator.ofFloat(myViewGroup, "translationY", 0f, -200 );
anim.setInterpolator(bounceInterpolator);
anim.setDuration(1100).start();

This will trigger a smooth animation with a bounce effect and really move the views not like animation prior to Honeycomb. From the docs :

The previous animations changed the visual appearance of the target objects... but they didn't actually change the objects themselves.

Decoy
  • 1,570
  • 11
  • 19
2

Also you can resize with Google's new Spring animations.

SpringAnimation creation method:

fun getSpringAnimation(view: View, springAnimationType: FloatPropertyCompat<View>, finalPosition: Float): SpringAnimation {
    val animation = SpringAnimation(view, springAnimationType )
    // create a spring with desired parameters
    val spring = SpringForce()
    spring.finalPosition = finalPosition
    spring.stiffness = SpringForce.STIFFNESS_VERY_LOW // optional
    spring.dampingRatio = SpringForce.DAMPING_RATIO_NO_BOUNCY // optional
    // set your animation's spring
    animation.spring = spring
    return animation
}

Usage (Resize to 80% of the original view size.)

 getSpringAnimation(view, SpringAnimation.SCALE_X, 0.8f).start()
 getSpringAnimation(view, SpringAnimation.SCALE_Y, 0.8f).start()
Mete
  • 2,627
  • 1
  • 22
  • 35