'How to make smooth MotionLayout?

I have a RecyclerView in my application, there is a layout above and below it, I need the top layout to collapse while I scroll the RecyclerView, and when the RecyclerView goes down to the end, the bottom layout appears. I'm trying to do it with MotionLayout. But I ran into a problem, the appearance and disappearance of the layout occur immediately, without smoothness. This is how it looks like now:

enter image description here enter image description here

The bottom layout appears before the full scroll and should only appear at the end of the RecyclerView scroll. And the top layout also disappears instantly. And I need it to happen like in the video:

enter image description here

Here is my screen:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/motionLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/scene_02_autocomplete_false">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/constraintLayout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toBottomOf="@+id/linearLayout">

        <VideoView
            android:id="@+id/sphereVideoView"
            android:layout_width="242dp"
            android:layout_height="240dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/mainOptimizationText"
            style="@style/TextStyleBold700"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="87dp"
            android:text="@string/perfect"
            android:textAlignment="center"
            android:textColor="@color/text_dark"
            android:textSize="24sp"
            app:layout_constraintEnd_toEndOf="@+id/sphereVideoView"
            app:layout_constraintStart_toStartOf="@+id/sphereVideoView"
            app:layout_constraintTop_toTopOf="@+id/sphereVideoView" />

        <TextView
            android:id="@+id/mainOptimizationSecondText"
            style="@style/TextStyleRegular400"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginEnd="8dp"
            android:text="@string/phone_is_optimized_and_cleaned"
            android:textAlignment="center"
            android:textColor="@color/text_dark"
            android:textSize="12sp"
            app:layout_constraintEnd_toEndOf="@+id/sphereVideoView"
            app:layout_constraintStart_toStartOf="@+id/sphereVideoView"
            app:layout_constraintTop_toBottomOf="@+id/mainOptimizationText" />
    </androidx.constraintlayout.widget.ConstraintLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/mainRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layoutAnimation="@anim/layout_animation"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/constraintLayout" />

    <LinearLayout
        android:id="@+id/bottomLinear"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="@color/green_start"
        android:orientation="vertical"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/mainRecyclerView" />
    <!--    </androidx.constraintlayout.widget.ConstraintLayout>-->
    <LinearLayout
        android:id="@+id/linearLayout"
        style="@style/Widget.Toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:orientation="horizontal"
        app:layout_collapseMode="pin"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:layout_width="32dp"
            android:layout_height="44dp"
            android:layout_gravity="bottom"
            android:layout_marginStart="24dp"
            android:src="@drawable/ic_logo" />

        <TextView
            style="@style/TextStyleBold700"
            android:layout_width="0dp"
            android:layout_height="44dp"
            android:layout_gravity="bottom"
            android:layout_weight="1"
            android:gravity="center"
            android:text="@string/app_name"
            android:textColor="@color/text_dark"
            android:textSize="18sp" />

        <ImageView
            android:id="@+id/burgerMenu"
            android:layout_width="34dp"
            android:layout_height="34dp"
            android:layout_gravity="center|end|bottom"
            android:layout_marginEnd="24dp"
            android:layout_marginBottom="4dp"
            android:background="@drawable/ic_burger_menu" />

    </LinearLayout>
</androidx.constraintlayout.motion.widget.MotionLayout>

Here is my scene:

<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:motion="http://schemas.android.com/apk/res-auto">

    <Transition
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@+id/start"
        motion:duration="1000">
        <OnSwipe
            motion:dragDirection="dragUp"
            motion:onTouchUp="stop"
            motion:touchAnchorId="@id/constraintLayout"
            motion:touchAnchorSide="right" />
        <KeyFrameSet>
            <KeyAttribute
                android:scaleX="0"
                android:scaleY="0"
                motion:framePosition="50"
                motion:motionTarget="@id/constraintLayout" />
<!--            <KeyPosition-->
<!--                motion:framePosition="50"-->
<!--                motion:keyPositionType="pathRelative"-->
<!--                motion:motionTarget="@id/constraintLayout" />-->
        </KeyFrameSet>
    </Transition>

    <ConstraintSet android:id="@+id/start">
        <Constraint android:id="@id/constraintLayout">
            <Layout
                android:layout_width="242dp"
                android:layout_height="240dp"
                android:layout_marginTop="64dp"
                motion:layout_constraintBottom_toTopOf="@+id/mainRecyclerView"
                motion:layout_constraintEnd_toEndOf="parent"
                motion:layout_constraintStart_toStartOf="parent"
                motion:layout_constraintTop_toTopOf="parent" />
        </Constraint>
        <Constraint android:id="@id/mainOptimizationText">
            <Layout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="87dp"
                motion:layout_constraintEnd_toEndOf="@+id/sphereVideoView"
                motion:layout_constraintStart_toStartOf="@+id/sphereVideoView"
                motion:layout_constraintTop_toTopOf="@+id/sphereVideoView"  />
        </Constraint>
        <Constraint android:id="@id/mainOptimizationSecondText">
            <Layout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:layout_marginEnd="8dp"
                motion:layout_constraintEnd_toEndOf="@+id/sphereVideoView"
                motion:layout_constraintStart_toStartOf="@+id/sphereVideoView"
                motion:layout_constraintTop_toBottomOf="@+id/mainOptimizationText"  />
        </Constraint>
        <Constraint android:id="@id/mainRecyclerView">
            <Layout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                motion:layout_constraintBottom_toBottomOf="parent"
                motion:layout_constraintEnd_toEndOf="parent"
                motion:layout_constraintStart_toStartOf="parent"
                motion:layout_constraintTop_toBottomOf="@+id/constraintLayout" />
        </Constraint>
        <Constraint android:id="@id/bottomLinear">
            <Layout
                android:layout_width="match_parent"
                android:layout_height="100dp"
                motion:layout_constraintEnd_toEndOf="parent"
                motion:layout_constraintStart_toStartOf="parent"
                motion:layout_constraintTop_toBottomOf="parent" />
        </Constraint>
    </ConstraintSet>

    <ConstraintSet
        android:id="@+id/end"
        motion:deriveConstraintsFrom="@id/start">

        <Constraint android:id="@id/constraintLayout">
            <Layout
                android:layout_width="242dp"
                android:layout_height="0dp"
                motion:layout_constraintBottom_toTopOf="parent"
                motion:layout_constraintEnd_toEndOf="parent"
                motion:layout_constraintStart_toStartOf="parent" />
        </Constraint>
        <Constraint android:id="@id/mainOptimizationText">
            <Layout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="0dp"
                motion:layout_constraintEnd_toEndOf="@+id/sphereVideoView"
                motion:layout_constraintStart_toStartOf="@+id/sphereVideoView"
                motion:layout_constraintTop_toTopOf="@+id/sphereVideoView"  />
        </Constraint>
        <Constraint android:id="@id/mainOptimizationSecondText">
            <Layout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:layout_marginEnd="8dp"
                motion:layout_constraintEnd_toEndOf="@+id/sphereVideoView"
                motion:layout_constraintStart_toStartOf="@+id/sphereVideoView"
                motion:layout_constraintTop_toBottomOf="@+id/mainOptimizationText"  />
        </Constraint>
        <Constraint android:id="@id/mainRecyclerView">
            <Layout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                motion:layout_constraintBottom_toTopOf="@+id/bottomLinear"
                motion:layout_constraintEnd_toEndOf="parent"
                motion:layout_constraintStart_toStartOf="parent"
                motion:layout_constraintTop_toBottomOf="@+id/constraintLayout" />
        </Constraint>
        <Constraint android:id="@id/bottomLinear">
            <Layout
                android:layout_width="match_parent"
                android:layout_height="100dp"
                motion:layout_constraintBottom_toBottomOf="parent"
                motion:layout_constraintEnd_toEndOf="parent"
                motion:layout_constraintStart_toStartOf="parent"
                motion:layout_constraintTop_toBottomOf="@+id/mainRecyclerView" />
        </Constraint>
    </ConstraintSet>

</MotionScene>

And tell me, please, is it possible, too, through MotionLayout, to make such an animation of the collapse of the upper layout (which is with a circle), as in the video?

Update: I managed to achieve smoothness but the upper part still does not leave like in the video. And the bottom one still appears before the RecyclerView scrolls. Updated screen and scene code. Here's what it looks like now:

enter image description here Also, one of the texts is missing.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source