UnaDeKalamares
UnaDeKalamares

Reputation: 193

MotionLayout multiple Transitions

First of all, I'm using androidx.constraintlayout:constraintlayout:2.0.0-beta1, as beta2 is messing a lot of layouts in our app.

I was trying to make MotionLayout play two different transitions under different circumstances:

1) When clicking on certain item, I want to make it expand and collapse; 2) When scrolling, the idea was to make another item to collapse and expand (similarly to a collapsing toolbar).

After some research, I've found out that MotionLayout won't accept more than one Transition tag inside it's layoutDescription (it'll only load the first one it can find). So, in order for my implementation to work, I've done it this way:

Inside my MotionScene, I only have the scrolling Transition element, with both of its ConstraintSets. I also define the neccesary ConstraintSets for the click animations.

<Transition
    android:id="@+id/scroll_transition"
    app:constraintSetStart="@id/notifications_expanded"
    app:constraintSetEnd="@id/notifications_collapsed">

    <OnSwipe
        app:dragDirection="dragUp"
        app:touchAnchorId="@id/swiperefresh_layout"
        app:touchAnchorSide="top"
        app:moveWhenScrollAtTop="true"/>

</Transition>

<ConstraintSet android:id="@+id/notifications_expanded">
    <Constraint android:id="@id/notifications"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/header_info_container"
        app:layout_constraintEnd_toEndOf="parent"/>
</ConstraintSet>

<ConstraintSet android:id="@+id/notifications_collapsed">
    <Constraint android:id="@id/notifications"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toBottomOf="@id/header_info_container"
        app:layout_constraintEnd_toEndOf="parent"/>
</ConstraintSet>

<ConstraintSet android:id="@+id/header_collapsed">

    <Constraint android:id="@id/header_info_container"
        android:visibility="gone"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/header_layout"
        app:layout_constraintEnd_toEndOf="parent"/>

</ConstraintSet>

<ConstraintSet android:id="@+id/header_expanded">

    <Constraint android:id="@id/header_info_container"
        android:visibility="visible"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/header_layout"
        app:layout_constraintEnd_toEndOf="parent"/>

</ConstraintSet>

In my layout's xml, I set the layoutDescription;

<androidx.constraintlayout.motion.widget.MotionLayout
        android:id="@+id/motion_layout"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layoutDescription="@xml/transitions">

The scrolling Transition works as expected flawlessly. In order for the click animation to actually work, I call it manually:

if (headerInfoContainer.getVisibility() == View.VISIBLE) {
    motionLayout.setTransition(R.id.header_expanded, R.id.header_collapsed);
    motionLayout.setTransitionDuration(300);
    motionLayout.transitionToEnd();
} else {
    motionLayout.setTransition(R.id.header_collapsed, R.id.header_expanded);
    motionLayout.setTransitionDuration(300);
    motionLayout.transitionToEnd();
}

However, after that snippet, the scrolling stops working. I suspect it has been disabled, but I cannot find how to put it back as it was before. The lack of documentation doesn't help either.

Thank you in advance!

Upvotes: 3

Views: 3221

Answers (1)

Rodrigo Salomao
Rodrigo Salomao

Reputation: 153

I know it is an old post, but I will try to answer for others that might have the same problem. Actually, yes you can have more than 1 Transition in your MotionScene, but they will work only one at a time. I might not fully understand what you need but if you want other views, inside your header, animate while your header is collapsing/expanding, you need to set theirs Constraint properties inside your ConstraintSet. Remember ConstraintSet is like a state of your views, it goes from one state to another, so for every view that needs to change on a specific set you need to set new views`s properties with a ConstraintSet. Something like:

   <Transition
    android:id="@+id/scroll_transition"
    app:constraintSetStart="@id/notifications_expanded"
    app:constraintSetEnd="@id/notifications_collapsed">

    <OnSwipe
        app:dragDirection="dragUp"
        app:touchAnchorId="@id/swiperefresh_layout"
        app:touchAnchorSide="top"
        app:moveWhenScrollAtTop="true"/>

</Transition>

<ConstraintSet android:id="@+id/notifications_expanded">
    ... How your views should change from default layout when getting on this state
</ConstraintSet>

<ConstraintSet android:id="@+id/notifications_collapsed">
    ... How your views should change from default layout when getting on this state
</ConstraintSet>

On your <Transition> tag you tell MotionScene what is the Start and End state.

Upvotes: 1

Related Questions