Can’t manage to preform two actions on two different elements in Motionlayout | Android Studio

Issue

I have a motion layout that moves back and forth between covering the element below it, and showing it when it is swiped up, this element (the dashboard) has a swipe up image on it that lets the user know it’s swipable. The problem here is that I want the “swipe up arrow” to disappear after getting swiped.

But I’m faced with several problems: the motion layout doesn’t recognize elements other than the one below it, so it seems that a motion layout can’t do transitions for more than one element.

  • So I can’t use the dashboard motion layout to hide the swipe up image after the swipe, I tried and I it didn’t work and never gave me an error

  • I can’t turn the swipe up image into a motion layout either because it won’t recognize the dashboard

So I thought I would do it programmatically. Whenever the dashboard (the one in black) element is swiped up, the swipe up image is set to invisible, but having started to set that up, the dashboard element now ignores the swipe up listener from the motion layout and acknowledges the kotlin listener.

I can only think of several solutions, being a new android dev. One of which is adding a swipe up listener to the dashboard programmatically and using that to transition it upwards and get the arrow to disappear OR find a way to get the motion layout to transition the dashboard upward and remove the swipe up image once its been swiped

Neither of which is something I know how to do, I’m also open to more efficient alternatives

How it looks before its been swiped

How it should look after

main activity:

<?xml version"1.0" encoding"utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android"http://schemas.android.com/apk/res/android"
xmlns:tools"http://schemas.android.com/tools"
xmlns:app"http://schemas.android.com/apk/res-auto"
android:layout_width"match_parent"
android:layout_height"match_parent"
android:background"@color/white"
tools:context".MainActivity">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width"match_parent"
        android:layout_height"500dp"
        app:layout_constraintBottom_toBottomOf"parent"
        app:layout_constraintEnd_toEndOf"parent"
        app:layout_constraintStart_toStartOf"parent">

        <androidx.cardview.widget.CardView
            android:id"@+id/dashboard"
            android:layout_width"match_parent"
            android:layout_height"match_parent"
            app:cardBackgroundColor"@color/green"
            app:layout_constraintEnd_toEndOf"parent"
            app:layout_constraintStart_toStartOf"parent"
            app:layout_constraintTop_toTopOf"parent">

        </androidx.cardview.widget.CardView>
    </androidx.constraintlayout.widget.ConstraintLayout>

    <androidx.constraintlayout.motion.widget.MotionLayout
        android:id"@+id/constraintLayout12"
        android:layout_width"match_parent"
        android:layout_height"100dp"
        android:elevation"20dp"
        app:layoutDescription"@xml/activity_main_light_copy_2_xml_constraintlayout12_scene"
        app:layout_constraintBottom_toBottomOf"parent"
        app:layout_constraintEnd_toEndOf"parent"
        app:layout_constraintStart_toStartOf"parent">

        <ImageView
            android:id"@+id/swipeUpPic"
            android:layout_width"match_parent"
            android:layout_height"100dp"
            app:layout_constraintBottom_toBottomOf"@id/dashboard"
            app:layout_constraintEnd_toEndOf"@id/dashboard"
            app:layout_constraintStart_toStartOf"@id/dashboard"
            app:srcCompat"@drawable/scroll_image" />
    </androidx.constraintlayout.motion.widget.MotionLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

Motion layout:

<?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:touchAnchorId"@id/dashboard"
            motion:dragDirection"dragUp"
            motion:touchAnchorSide"top" />

    </Transition>

    <ConstraintSet android:id"@+id/start">
        <Constraint
            android:id"@id/dashboard"
            android:layout_width"match_parent"
            android:layout_height"match_parent"
            motion:layout_constraintEnd_toEndOf"parent"
            motion:layout_constraintStart_toStartOf"parent" >
        </Constraint>

        <Constraint
            android:id"@id/swipeUpPic"
            android:layout_width"match_parent"
            android:layout_height"match_parent"
            android:visibility"visible"
            motion:layout_constraintEnd_toEndOf"parent"
            motion:layout_constraintStart_toStartOf"parent" >
        </Constraint>

    </ConstraintSet>

    <ConstraintSet android:id"@+id/end">
        <Constraint
            android:id"@id/dashboard"
            android:layout_width"match_parent"
            android:layout_height"400dp"
            motion:layout_constraintEnd_toEndOf"parent"
            motion:layout_constraintStart_toStartOf"parent" >
        </Constraint>

        <Constraint
            android:id"@id/swipeUpPic"
            android:layout_width"match_parent"
            android:layout_height"match_parent"
            motion:layout_constraintEnd_toEndOf"parent"
            motion:layout_constraintStart_toStartOf"parent"
            android:visibility"invisible">
        </Constraint>
    </ConstraintSet>
</MotionScene>

Solution

Let me start by saying, I totally agree with @hoford.

The best approach would be to flatten your MotionLayout, however you can show/hide your swipe up button by adding a TransitionListener to your MotionLayout. Use addTransitionListener()

You can either use:

  • onTransitionStarted() Called when a drawer is about to start a transition. Note. startId may be -1 if starting from an “undefined state”. The startId and endId refers to the ConstraintSet ids.
  • onTransitionChange() Called when a drawer’s position changes. Where you can even track the current (transition) progress and apply the same transition state to your own View(s).

Answered By – Abbas

Leave a Comment