Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android MotionLayout: How to handle both click and swipe events on same view? (video examples included)

I need to implement this in my app. It's best if you looked at the video examples because I can't explain it precisely with words:

Drag motion : https://streamable.com/i0aen

Click motion :https://streamable.com/7eahj

I was able to implement them independent one from another. But I can't manage to do them together. I was using a single motion scene file. I can comment out one transition and the other one works, but If I leave them both the layout doesn't behave at all, I guess one transition captures another and it stops. Is there a way to implement both these events on same view? Here is the code for motion_scene:

<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:motion="http://schemas.android.com/apk/res-auto">
<!--    <Transition-->
<!--        android:id="@+id/dragTransition"-->
<!--        motion:constraintSetEnd="@+id/endDrag"-->
<!--        motion:constraintSetStart="@+id/startDrag"-->
<!--        motion:duration="1000">-->
<!--        <OnSwipe-->
<!--            motion:dragDirection="dragDown"-->
<!--            motion:touchAnchorId="@id/menuBtnFrFr"-->
<!--            motion:touchAnchorSide="top" />-->
<!--    </Transition>-->

    <Transition
        android:id="@+id/clickTransition"
        motion:constraintSetEnd="@+id/endClick"
        motion:constraintSetStart="@+id/startClick"
        motion:duration="300">
        <OnClick motion:targetId="@id/menuBtnFrFr" />
    </Transition>

    <ConstraintSet android:id="@+id/startDrag">
        <Constraint
            android:id="@+id/menuBtnFrFr"
            android:layout_width="250dp"
            android:layout_height="250dp"
            android:layout_marginLeft="75dp"
            android:layout_marginRight="75dp"
            android:background="#00000000"
            android:src="@drawable/logo"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintDimensionRatio="1:1"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
        <Constraint
            android:id="@+id/bgCircleOutside"
            android:layout_width="350dp"
            android:layout_height="350dp"
            android:layout_below="@id/top_label"
            android:layout_gravity="center"
            android:layout_margin="15dp"
            android:background="@drawable/circle_dark"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintDimensionRatio="1:1"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
        <Constraint
            android:id="@+id/bgCircle"
            android:layout_width="300dp"
            android:layout_height="300dp"
            android:layout_gravity="center"
            android:layout_margin="45dp"
            android:background="@drawable/circle"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintDimensionRatio="1:1"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
        <Constraint
            android:id="@+id/uploadBtn"
            android:layout_width="@dimen/button_size"
            android:layout_height="wrap_content"
            android:background="#00000000"
            android:visibility="gone"
            android:orientation="vertical"
            android:layout_marginTop="440dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintHorizontal_bias="0.5"
            motion:layout_constraintVertical_bias="0.5"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
        <Constraint
            android:id="@+id/recordBtn"
            android:layout_width="@dimen/button_size"
            android:layout_height="wrap_content"
            android:background="#00000000"
            android:orientation="vertical"
            android:scaleType="fitXY"
            android:gravity="center"
            android:visibility="gone"
            android:layout_marginTop="400dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintHorizontal_bias="0.24"
            motion:layout_constraintVertical_bias="0.5"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
        <Constraint
            android:id="@+id/gifBtn"
            android:layout_width="@dimen/button_size"
            android:layout_height="wrap_content"
            android:background="#00000000"
            android:orientation="vertical"
            android:scaleType="fitCenter"
            android:gravity="center"
            android:layout_marginTop="400dp"
            android:visibility="gone"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintHorizontal_bias="0.76"
            motion:layout_constraintVertical_bias="0.5">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/endDrag">
        <Constraint
            android:id="@+id/menuBtnFrFr"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:layout_marginLeft="75dp"
            android:layout_marginRight="75dp"
            android:background="#00000000"
            android:src="@drawable/logo"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintDimensionRatio="1:1"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintVertical_bias="0.98">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="0" />
        </Constraint>
        <Constraint
            android:id="@+id/bgCircle"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:layout_gravity="center"
            android:layout_margin="45dp"
            android:background="@drawable/circle"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintDimensionRatio="1:1"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
        <Constraint
            android:id="@+id/bgCircleOutside"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:layout_below="@id/top_label"
            android:layout_gravity="center"
            android:layout_margin="15dp"
            android:background="@drawable/circle_dark"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintDimensionRatio="1:1"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
        <Constraint
            android:id="@+id/uploadBtn"
            android:layout_width="@dimen/button_size"
            android:layout_height="wrap_content"
            android:background="#00000000"
            android:visibility="gone"
            android:orientation="vertical"
            android:layout_marginTop="440dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintHorizontal_bias="0.5"
            motion:layout_constraintVertical_bias="0.5"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
        <Constraint
            android:id="@+id/recordBtn"
            android:layout_width="@dimen/button_size"
            android:layout_height="wrap_content"
            android:background="#00000000"
            android:orientation="vertical"
            android:scaleType="fitXY"
            android:gravity="center"
            android:visibility="gone"
            android:layout_marginTop="400dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintHorizontal_bias="0.24"
            motion:layout_constraintVertical_bias="0.5"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
        <Constraint
            android:id="@+id/gifBtn"
            android:layout_width="@dimen/button_size"
            android:layout_height="wrap_content"
            android:background="#00000000"
            android:orientation="vertical"
            android:scaleType="fitCenter"
            android:gravity="center"
            android:layout_marginTop="400dp"
            android:visibility="gone"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintHorizontal_bias="0.76"
            motion:layout_constraintVertical_bias="0.5">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
    </ConstraintSet>
    <ConstraintSet android:id="@+id/startClick">
        <Constraint
            android:id="@+id/menuBtnFrFr"
            android:layout_width="250dp"
            android:layout_height="250dp"
            android:layout_marginLeft="75dp"
            android:layout_marginRight="75dp"
            android:background="#00000000"
            android:src="@drawable/logo"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintDimensionRatio="1:1"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
        <Constraint
            android:id="@+id/bgCircleOutside"
            android:layout_width="350dp"
            android:layout_height="350dp"
            android:layout_below="@id/top_label"
            android:layout_gravity="center"
            android:layout_margin="15dp"
            android:background="@drawable/circle_dark"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintDimensionRatio="1:1"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
        <Constraint
            android:id="@+id/bgCircle"
            android:layout_width="300dp"
            android:layout_height="300dp"
            android:layout_gravity="center"
            android:layout_margin="45dp"
            android:background="@drawable/circle"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintDimensionRatio="1:1"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
        <Constraint
            android:id="@+id/uploadBtn"
            android:layout_width="@dimen/button_size"
            android:layout_height="wrap_content"
            android:background="#00000000"
            android:orientation="vertical"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintHorizontal_bias="0.5"
            motion:layout_constraintVertical_bias="0.5"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
        <Constraint
            android:id="@+id/recordBtn"
            android:layout_width="@dimen/button_size"
            android:layout_height="wrap_content"
            android:background="#00000000"
            android:orientation="vertical"
            android:scaleType="fitXY"
            android:gravity="center"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintHorizontal_bias="0.24"
            motion:layout_constraintVertical_bias="0.5"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
        <Constraint
            android:id="@+id/gifBtn"
            android:layout_width="@dimen/button_size"
            android:layout_height="wrap_content"
            android:background="#00000000"
            android:orientation="vertical"
            android:scaleType="fitCenter"
            android:gravity="center"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintHorizontal_bias="0.76"
            motion:layout_constraintVertical_bias="0.5">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/endClick">
        <Constraint
            android:id="@+id/menuBtnFrFr"
            android:layout_width="250dp"
            android:layout_height="250dp"
            android:layout_marginLeft="75dp"
            android:layout_marginRight="75dp"
            android:layout_marginBottom="35dp"
            android:background="#00000000"
            android:src="@drawable/logo"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintDimensionRatio="1:1"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
        <Constraint
            android:id="@+id/bgCircle"
            android:layout_width="350dp"
            android:layout_height="350dp"
            android:layout_gravity="center"
            android:layout_margin="45dp"
            android:background="@drawable/circle"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintDimensionRatio="1:1"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent"
            android:layout_marginBottom="35dp">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
        <Constraint
            android:id="@+id/bgCircleOutside"
            android:layout_width="600dp"
            android:layout_height="600dp"
            android:layout_below="@id/top_label"
            android:layout_gravity="center"
            android:layout_margin="15dp"
            android:background="@drawable/circle_dark"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintDimensionRatio="1:1"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent"
            android:layout_marginBottom="35dp">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
        <Constraint
            android:id="@+id/uploadBtn"
            android:layout_width="@dimen/button_size"
            android:layout_height="wrap_content"
            android:background="#00000000"
            android:orientation="vertical"
            android:layout_marginTop="440dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintHorizontal_bias="0.5"
            motion:layout_constraintVertical_bias="0.5"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
        <Constraint
            android:id="@+id/recordBtn"
            android:layout_width="@dimen/button_size"
            android:layout_height="wrap_content"
            android:background="#00000000"
            android:orientation="vertical"
            android:scaleType="fitXY"
            android:gravity="center"
            android:layout_marginTop="400dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintHorizontal_bias="0.24"
            motion:layout_constraintVertical_bias="0.5"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
        <Constraint
            android:id="@+id/gifBtn"
            android:layout_width="@dimen/button_size"
            android:layout_height="wrap_content"
            android:background="#00000000"
            android:orientation="vertical"
            android:scaleType="fitCenter"
            android:gravity="center"
            android:layout_marginTop="400dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintHorizontal_bias="0.76"
            motion:layout_constraintVertical_bias="0.5">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
    </ConstraintSet>
</MotionScene> 

Is this possible to implement on same view anyway? If not is there some suggestions on how would you create this layout? Thanks in advance.

like image 837
Vuk Vukcevic Avatar asked Feb 03 '20 13:02

Vuk Vukcevic


1 Answers

Yes it's very easy. Just click on the indicator line which you use to preview your motion layout. In the attribute window you can add onclick and onswipe method simultaneously. Just add the target Id and action. Here you go. screenshot

like image 92
Subhra Mondal Avatar answered Oct 20 '22 12:10

Subhra Mondal