Animate LayoutParams changes in ConstraintLayout
Asked Answered
P

4

12

I am creating app in which there is screen with searchBar by this lib. My activity layout looks like this:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<android.support.constraint.ConstraintLayout
        android:id="@+id/wrapper"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:animateLayoutChanges="true">

    <TextView
            android:id="@+id/title"
            android:textColor="@color/colorPrimary"
            android:text="@string/mainScreenTitle"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:textAlignment="center"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            android:paddingTop="100dp"/>

    <com.arlib.floatingsearchview.FloatingSearchView
            android:id="@+id/searchView"
            android:layout_width="0dp"
            android:layout_height="50dp"
            android:layout_marginTop="100dp"
            android:animateLayoutChanges="true"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/title"/>

</android.support.constraint.ConstraintLayout>

</RelativeLayout>

There i have to move FloatingSearchingView to top of screen and change height to for example 500dp - like this:

app:layout_constraintTop_toTopOf="parent"
android:layout_height="500dp"

And later i will have to move it back and change height again to default value

app:layout_constraintTop_toBottomOf="@+id/title"
android:layout_height="50dp"

The problem is, i have to animate it. I have spent a lot of time searching for solution but unfortunately i didnt find anything.

Party answered 8/5, 2017 at 15:3 Comment(0)
M
15

I had to animate the TextView height inside a ConstraintLayout.

 <androidx.constraintlayout.widget.ConstraintLayout
                ...
                android:animateLayoutChanges="true"
                >

                <TextView
                 ...

I first informed the ConstraintLayout that the layout was about to change:

constraintlayout.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);

and then updated the textView height (or whatever other param)

textView.getLayoutParams().height = 200;
textView.requestLayout();

for something simple as that, no need to set animators or involve other libraries.

Mimosaceous answered 15/7, 2021 at 8:59 Comment(1)
This works perfectly! Didin't know of this one yet. I understand the need for requestLayout(), but somehow it is also working without it. Might be only for newer SDK version allthough. Edit: "This has been around since API 11 aka Honeycomb" omg! proandroiddev.com/…Horsepowerhour
A
2

@beeb's version didn't work for me either, unfortunately. Although the question is old, here is a solution that worked for me, using the TransitionManager. It's a bit "redundant", as you have to duplicate some code, but therefor very easy and includes only two basic steps:

  1. Create two layout.xml files. One for each state (before/after animation). If your constraint layout is one of multiple children of a parent layout, you can create two files containing only this constraint layout and include the version you wan't at app-start via <include @layout=""/>, where previously you constraint layout has been. That way, you don't have to duplicate the entire layout file. This however caused the findViewById() method to return null, when my include element had an id. So be careful with this.

In your case this would be e.g.: floating_searching_view_at_bottom.xml:

<com.arlib.floatingsearchview.FloatingSearchView
    android:id="@+id/searchView"
    android:layout_width="0dp"
    android:layout_height="50dp"
    android:layout_marginTop="100dp"
    android:animateLayoutChanges="true"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/title"
    android:layout_height="50dp" />

and floating_searching_view_at_top.xml:

<com.arlib.floatingsearchview.FloatingSearchView
    android:id="@+id/searchView"
    android:layout_width="0dp"
    android:layout_height="50dp"
    android:layout_marginTop="100dp"
    android:animateLayoutChanges="true"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/title"
    android:layout_height="50dp"
    app:layout_constraintTop_toTopOf="parent"
    android:layout_height="500dp" />
  1. Animate the transition between these layout files using TransitionManager:
boolean toggle = false // you should give this guy a more descriptive name!
Context context = this; // in scope of the activity.

public void animateTransition() {
    // Load ConstraintSets from the two layouts
    ConstraintSet atBottom = new ConstraintSet();
    ConstraintSet atTop    = new ConstraintSet();
    atBottom.clone(context, R.layout.floating_searching_view_at_bottom);
    atTop.clone(context, R.layout.floating_searching_view_at_top);

    // apply ConstraintSet depending on "toggle"
    ConstraintSet newLayout = (toggle) ? expanded : collapsed;
    TransitionManager.beginDelayedTransition(constraintLayout); 
    newLayout.applyTo(constraintLayout);

    // invert the toggle
    toggle = !toggle;
}

Note: 1. Make sure context is of type Activity and you're using an AppCompat theme. I accidentally used getApplicationContext(), what obviously resulted in a crash. 2. If you are receiving an NPE on your constraintk

Antigua answered 24/1, 2020 at 13:53 Comment(0)
D
0

Try to use Animation class for this:

Animation animation = new Animation() {

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        LayoutParams params = yourView.getLayoutParams();

        // modify your layout params here

        yourView.setLayoutParams(params);
    }
};
animation.setDuration(500); // in ms
yourView.startAnimation(animation);
Dungeon answered 8/5, 2017 at 15:28 Comment(2)
I do params.topToBottom = -1 and params.topToTop = R.id.wrapper inside applyTransformation method but it still has no animation :cParty
still has no animationImpeachment
M
0

What worked for me was to use a ValueAnimator

val constraintAnimator : ValueAnimator = ValueAnimator.ofInt(1, 200).apply {

    duration = 2000

    addUpdateListener { updatedAnimation ->

        val updatedValue = updatedAnimation.animatedValue as Int

        val params = yourView.layoutParams
        params.width = updatedValue
        yourView.layoutParams = params

    }

    start()
}
Mor answered 21/3, 2023 at 13:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.