11

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.

Qiteq
  • 675
  • 1
  • 6
  • 22

4 Answers4

14

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.

Alberto M
  • 1,608
  • 1
  • 18
  • 42
  • 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! https://proandroiddev.com/the-little-secret-of-android-animatelayoutchanges-e4caab2fddec – Boy Jul 22 '21 at 03:36
1

@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

Hamburg is nice
  • 369
  • 4
  • 10
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);
beeb
  • 1,615
  • 1
  • 12
  • 24
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()
}
Joseph Williamson
  • 771
  • 1
  • 6
  • 18