Search code examples
androidkotlinandroid-constraintlayoutandroidxandroid-motionlayout

Android motion scene for a image view


I am new to MotionLayout. I followed a simple example where the MotionLayout contains a single element say Button and this was quite easy to generate a MotionScene for it. However I have a MotionLayout which has several elements in it.

The layout looks like this -

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/details_view_scene">

    <ScrollView
        android:id="@+id/scroll_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/details_image"
                style="@style/detailsImage"
                app:layout_constraintDimensionRatio="h,16:9"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <com.google.android.material.textview.MaterialTextView
                android:id="@+id/name_label"
                style="@style/textTitle"
                android:text="@string/name"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/details_image" />

            <com.google.android.material.textview.MaterialTextView
                android:id="@+id/name_value"
                style="@style/textSubTitle"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/name_label" />

            <com.google.android.material.floatingactionbutton.FloatingActionButton
                android:id="@+id/like_button"
                style="@style/floatingButton"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:srcCompat="@drawable/ic_profile_like" />

            <ImageView
                android:id="@+id/like_image"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/ic_profile_like"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                android:visibility=“invisible”/>
        </androidx.constraintlayout.widget.ConstraintLayout>
    </ScrollView>
</androidx.constraintlayout.motion.widget.MotionLayout>

The problem is when the floating action button with id like_button is pressed, I want the imageview with id like_image to be visible and should transition from the floating action button to the top image view with id details_image.

Is this possible with MotionLayout?


Solution

  • For the 1st question:

    After the transition to the end, I want the image to be invisible.

    You should read KeyFrameSet: Specifies location and attributes for views over the course of the motion sequence.

    At frame 0, set alpha (or visibility) of image to 0.0 (invisible), At near last frame 99, set alpha (or visibility) of image to 1.0 (visible), At frame 100, set alpha (or visibility) of image to 0.0 (invisible),

    So when you click button, the alpha of image will be from 0 -> 1 -> 0.

    For the 2nd question:

    On first button click, the image moves from bottom to top which is expected. On second button click, the image still stays at the top and clicking on the image moves it down. Is there a way to reset the transition on every start -> end transition

    Add a MotionLayout.TransitionListener to your MotionLayout, so when transition is complete, set progress to 0 (start state).