Sony
Sony

Reputation: 7196

Scale a layout to match parent with animation

In my sample project i have a linear layout, its height is set to wrap content in xml and there is also a fragment below it which takes all the remaining space. The fragment contains a button which when clicked will remove the fragment and the height of the linear layout is set to match parent. I tried adding android:animateLayoutChanges="true" but the transition from wrap_content to match_parent is not smooth. How can i animate from android:layout_height="wrap_content" to android:layout_height="match_parent"

Here is the layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:background="@drawable/bg"
          android:orientation="vertical"
          android:id="@+id/layoutRoot"
          tools:context=".MainActivity">

<LinearLayout
    android:layout_width="match_parent"
    android:id="@+id/cloudHolder"
    android:orientation="vertical"
    android:animateLayoutChanges="true"
    android:gravity="center"
    android:layout_height="wrap_content">
    <ImageButton
        android:layout_width="100dp"
        android:layout_gravity="center"
        android:layout_height="100dp"
        android:background="@drawable/play"/>
</LinearLayout>

Upvotes: 2

Views: 6862

Answers (4)

tdjprog
tdjprog

Reputation: 719

try this:

private void animateViewToMatchParent(final View target) {
    int fromValue = target.getHeight();
    int toValue = ((View) target.getParent()).getHeight();

    ValueAnimator animator = ValueAnimator.ofInt(fromValue, toValue);

    animator.setDuration(250);
    animator.setInterpolator(new DecelerateInterpolator());
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            target.getLayoutParams().height = (int) animation.getAnimatedValue();
            target.requestLayout();
        }
    });
    animator.start();
}

Upvotes: 0

Hassan Badawi
Hassan Badawi

Reputation: 302

@tdjprog Answer with some edit

1 - Stritch

    private void animateViewTostritch_height(final View target) {
        int fromValue = 0;
        // int fromValue = target.getHeight();

        // int toValue = ((View) target.getParent()).getHeight();// matchparent
        int toValue = (int) getResources().getDimension(R.dimen.dialog_header_height);//spesific hight
        // int toValue = (int) (getResources().getDimension(R.dimen.dialog_header_height) / getResources().getDisplayMetrics().density);

        ValueAnimator animator = ValueAnimator.ofInt(fromValue, toValue);

        animator.setDuration(2000);
        animator.setInterpolator(new DecelerateInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                target.getLayoutParams().height = (int) animation.getAnimatedValue();
                target.requestLayout();
            }
        });

        animator.start();
    }

Call animateViewTostritch_height(your_View);

2 - Scale %

public void scaleView(View v, float startScale, float endScale) {
    Animation anim = new ScaleAnimation(
            1f, 1f, // Start and end values for the X axis scaling
            startScale, endScale, // Start and end values for the Y axis scaling
            Animation.RELATIVE_TO_SELF, 0f, // Pivot point of X scaling
            Animation.RELATIVE_TO_SELF, 1f); // Pivot point of Y scaling
    anim.setFillAfter(true); // Needed to keep the result of the animation
    anim.setDuration(1000);
    v.startAnimation(anim);
}

Call scaleView(your_View,0f,10f); // 10f match parent

Upvotes: 1

David Heisnam
David Heisnam

Reputation: 2491

I think relying on animateLayoutChanges isn't a good idea. Try below code instead.

import android.view.ViewPropertyAnimator;

// In your activity
private int parentHeight;
private int childHeight;
private float childScaleFactor;


//In onCreate()
mChildView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        parentHeight = mParentView.getMeasuredHeight();
        childHeight = mChildView.getMeasuredHeight();
        childScaleFactor = parentHeight/childHeight;
    }
});


mChildView.animate()
    .scaleY(childScaleFactor)
    .setDuration(500)
    .start();

If this doesn't work, refer to this answer on another post

Upvotes: 0

Hussein El Feky
Hussein El Feky

Reputation: 6707

You may need to try adding android:animateLayoutChanges="true" in the parent layout itself like for example:

<LinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:background="@drawable/bg"
      android:orientation="vertical"
      android:animateLayoutChanges="true"
      android:id="@+id/layoutRoot"
      tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:id="@+id/cloudHolder"
        android:orientation="vertical"
        android:gravity="center"
        android:layout_height="wrap_content">

        <ImageButton
            android:layout_width="100dp"
            android:layout_gravity="center"
            android:layout_height="100dp"
            android:background="@drawable/play"/>

    </LinearLayout>

</LinearLayout>

If the above code doesn't work, you might need to take a look at:

Animation of height of LinearLayout container with ValueAnimator

Or

Animation in changing LayoutParams in LinearLayout

Upvotes: 0

Related Questions