androidandroid-layoutandroid-motionlayoutandroid-gestureandroid-touch-event

Add swipe gestures in addition to MotionLayout transition


I am using a MotionLayout setup with a dragUp Transition to toggle some layout on my view. (Basically you can drag up to see more information.) However, I would also like to be able to support "swipe left" and "swipe right" gestures to trigger other things in the app, but I cannot figure out how to listen for the swipe events without breaking my MotionLayout transition.

If I set an OnTouchListener on my view I can see the swipe events, but this seems to break the MotionLayout transition since I can no longer drag up for the extra info.

I think I might need some way to "pass through" swipe events in my OnTouchListener when they are up/down, but just calling super.onFling... does not seem to work. Otherwise I am hoping there is a different way to implement this swiping functionality that I have not stumbled across yet...

Any suggestions here would be greatly appreciated!


Solution

  • You just need to add more ConstraintSets and Transitions that go between them like this:

    <?xml version="1.0" encoding="utf-8"?>
    <MotionScene
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <Transition
            app:constraintSetStart="@id/start"
            app:constraintSetEnd="@id/middle">
            <OnSwipe
                app:touchAnchorId="@id/square"
                app:dragDirection="dragUp"
                app:touchAnchorSide="top"/>
        </Transition>
    
        <Transition
            app:constraintSetStart="@id/middle"
            app:constraintSetEnd="@id/left">
            <OnSwipe
                app:touchAnchorId="@id/square"
                app:dragDirection="dragLeft"
                app:touchAnchorSide="left"/>
        </Transition>
    
        <Transition
            app:constraintSetStart="@id/middle"
            app:constraintSetEnd="@id/right">
            <OnSwipe
                app:touchAnchorId="@id/square"
                app:dragDirection="dragRight"
                app:touchAnchorSide="left"/>
        </Transition>
    
        <ConstraintSet android:id="@+id/start">
            <Constraint android:id="@id/square">
                <Layout
                    android:layout_width="100dp"
                    android:layout_height="100dp"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    />
            </Constraint>
        </ConstraintSet>
    
        <ConstraintSet android:id="@+id/middle">
            <Constraint android:id="@id/square" >
                <Layout
                    android:layout_width="100dp"
                    android:layout_height="100dp"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    />
            </Constraint>
        </ConstraintSet>
    
        <ConstraintSet android:id="@+id/left">
            <Constraint android:id="@id/square" >
                <Layout
                    android:layout_width="100dp"
                    android:layout_height="100dp"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    />
            </Constraint>
        </ConstraintSet>
    
        <ConstraintSet android:id="@+id/right">
            <Constraint android:id="@id/square" >
                <Layout
                    android:layout_width="100dp"
                    android:layout_height="100dp"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    />
            </Constraint>
        </ConstraintSet>
    
    </MotionScene>
    

    If you want to see a fun working example here's a sliding tile puzzle I did.