StackOverflower
StackOverflower

Reputation: 5761

Animate top and bottom dimensions of a view

I need to do two things with a view:

  1. Move top dimension to the very top of the window
  2. Move bottom dimension to the very bottom of the window.

In short, I need the view to cover 100% of the parent view.

Translation animation didn't work because it moves the view but it doesn't increase the size.

Scale animation works but it stretches the content of the view and I don't want that. I want to increase the visible area, not stretch the content to fit the new dimensions.

What's the correct way to do this?

Upvotes: 8

Views: 2593

Answers (6)

krishan
krishan

Reputation: 1149

ValueAnimator anim = ValueAnimator.ofInt(viewToIncreaseHeight.getMeasuredHeight(), -100);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator valueAnimator) {
        int val = (Integer) valueAnimator.getAnimatedValue();
        ViewGroup.LayoutParams layoutParams = viewGroup.getLayoutParams();
        layoutParams.height = val;
        viewGroup.setLayoutParams(layoutParams);
    }
});
anim.setDuration(DURATION);
anim.start(); 

Upvotes: 0

smora
smora

Reputation: 719

Using ConstraintLayout with ConstrainSet should match your need in the most efficient way.

public class MainActivity extends AppCompatActivity {
    ConstraintSet mConstraintSet1 = new ConstraintSet(); // create a Constraint Set
    ConstraintSet mConstraintSet2 = new ConstraintSet(); // create a Constraint Set
    ConstraintLayout mConstraintLayout; // cache the ConstraintLayout
    boolean mOld = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Context context = this;
        mConstraintSet2.clone(context, R.layout.state2); // get constraints from layout
        setContentView(R.layout.state1);
        mConstraintLayout = (ConstraintLayout) findViewById(R.id.activity_main);
        mConstraintSet1.clone(mConstraintLayout); // get constraints from ConstraintSet
    }

    public void foo(View view) {
        TransitionManager.beginDelayedTransition(mConstraintLayout);
        if (mOld = !mOld) {
            mConstraintSet1.applyTo(mConstraintLayout); // set new constraints
        }  else {
            mConstraintSet2.applyTo(mConstraintLayout); // set new constraints
        }
    }
}

Source https://developer.android.com/reference/android/support/constraint/ConstraintSet.html

All you need is to define a second layout.xml with your expanded constraints and apply the second ConstraintSet to your view or activity when necessary.

Upvotes: 0

Nick
Nick

Reputation: 595

animateLayoutChanges="true" in the parent xml

+

.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

does the trick most of the times and it won't stretch the existing child views

Upvotes: 0

azizbekian
azizbekian

Reputation: 62189

That can be easily achieved with Transitions API.

With Transitions API you do not take care of writing animations, you just tell what you want the end values be and Transitions API would take care of constructing animations.

Having this xml as content view (a view in the center of the screen):

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:id="@+id/view"
        android:layout_width="120dp"
        android:layout_height="80dp"
        android:layout_gravity="center"
        android:background="@color/colorAccent" />

</FrameLayout>

In activity:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.item)

    val root = findViewById(R.id.root) as ViewGroup
    val view = findViewById(R.id.view)

    view.setOnClickListener {

        // After this line Transitions API would start counting the delta
        // and will take care of creating animations for each view in `root`
        TransitionManager.beginDelayedTransition(root)

        // By default AutoTransition would be applied,
        // but you can provide your transition with the second parameter

        // val transition = AutoTransition()
        // transition.duration = 2000
        // TransitionManager.beginDelayedTransition(root, transition)

        // We are changing size of the view to match parent
        val params = view.layoutParams
        params.height = ViewGroup.LayoutParams.MATCH_PARENT
        params.width = ViewGroup.LayoutParams.MATCH_PARENT

        view.requestLayout()
    }
}

Here's the output:

Platform's Transitions API (android.transition.TransitionManager) is available from API 19, but support libraries backport the functionality upto API 14 (android.support.transition.TransitionManager).

Upvotes: 12

zombie
zombie

Reputation: 5259

I like to keep everything as simple as it can be.

so my suggestion would be using a android Animating Layout Changes

Here is a sample:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true"
    android:animationCache="true">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/app_name"
        android:background="@color/colorPrimary"
        android:layout_gravity="center" />

</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {

    TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.textView);
    }

    @Override
    protected void onResume() {
        super.onResume();

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {

                View view = getWindow().getDecorView();

                int height = getWindow().getDecorView().getHeight();
                int width = getWindow().getDecorView().getWidth();
                textView.setLayoutParams(new LinearLayout.LayoutParams(width, height));

                LayoutTransition layoutTransition = ((ViewGroup) textView.getParent()).getLayoutTransition();
                layoutTransition.enableTransitionType(LayoutTransition.CHANGING);
            }
        }, 2000);
    }
}

Upvotes: 2

Matias Olocco
Matias Olocco

Reputation: 509

You can try using ValueAnimator as shown in this answer: https://stackoverflow.com/a/32835417/3965050

Note: I wanted to write this as a comment, but I don't have the reputation. This should not be considered as a full answer.

Upvotes: 1

Related Questions