MotionLayout - one transition disabling another

870 Views Asked by At

I have two transitions in one MotionScene:

<Transition
        android:id="@+id/swipeRightTransition"
        app:constraintSetEnd="@id/swipedRight"
        app:constraintSetStart="@+id/defaultPosition" >

        <OnSwipe
            app:maxAcceleration="60"
            app:dragDirection="dragRight"
            app:onTouchUp="autoComplete"
            app:touchAnchorId="@id/pieChart"
            app:touchAnchorSide="right"/>

    </Transition>

    <Transition
        android:id="@+id/swipeLeftTransition"
        app:constraintSetEnd="@id/swipedLeft"
        app:constraintSetStart="@+id/defaultPosition" >

        <OnSwipe
            app:maxAcceleration="60"
            app:dragDirection="dragLeft"
            app:onTouchUp="autoComplete"
            app:touchAnchorId="@id/pieChart"
            app:touchAnchorSide="left"/>

    </Transition>

If you disable the first transition "swipeRightTransition" with getTransition(R.id.swipeRightTransition).setEnable(false), the second will be disabled too! And setting "setEnable(true)" to the second has no effect, it will be disabled anyway. If you will disable the second transtion "swipeLeftTransition" the first transition works fine. I don't understand it at all.

Full scene code:

<?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">

    <ConstraintSet android:id="@+id/defaultPosition">
        <Constraint android:id="@+id/pieChart"
            android:layout_width="0dp"
            android:layout_height="220dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@id/leftArrowLayout"
            app:layout_constraintEnd_toStartOf="@id/rightArrowLayout"
            app:layout_constraintTop_toTopOf="parent"
            android:layout_gravity="center"/>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/swipedLeft">
        <Constraint android:id="@+id/pieChart"
            android:layout_width="220dp"
            android:layout_height="220dp"
            app:layout_constraintEnd_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/swipedRight">
        <Constraint android:id="@+id/pieChart"
            android:layout_width="220dp"
            android:layout_height="220dp"
            app:layout_constraintStart_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>
    </ConstraintSet>

    <Transition
        android:id="@+id/swipeRightTransition"
        app:constraintSetEnd="@id/swipedRight"
        app:constraintSetStart="@+id/defaultPosition" >

        <OnSwipe
            app:maxAcceleration="60"
            app:dragDirection="dragRight"
            app:onTouchUp="autoComplete"
            app:touchAnchorId="@id/pieChart"
            app:touchAnchorSide="right"/>

    </Transition>

    <Transition
        android:id="@+id/swipeLeftTransition"
        app:constraintSetEnd="@id/swipedLeft"
        app:constraintSetStart="@+id/defaultPosition" >

        <OnSwipe
            app:maxAcceleration="60"
            app:dragDirection="dragLeft"
            app:onTouchUp="autoComplete"
            app:touchAnchorId="@id/pieChart"
            app:touchAnchorSide="left"/>

    </Transition>
</MotionScene>

Please help!

1

There are 1 best solutions below

1
On BEST ANSWER

This is a bug/feature.

The first transition is the default transition. So at the start you are on that transition. Which gets disabled. So it cannot switch to the other transition because you are stuck on a transition that is disabled. The simple solution is to set the other transition at the same time.

so:

ml.setTransition(R.id.swipeLeftTransition);
ml.getTransition(R.id.swipeRightTransition).setEnable(false)

Testing with this:

<?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
    android:id="@+id/sLeft"
    motion:constraintSetStart="@+id/start"
    motion:constraintSetEnd="@+id/left">
    <OnSwipe
        motion:touchAnchorId="@id/view"
        motion:dragDirection="dragLeft" />
</Transition>
<Transition
    android:id="@+id/sRight"
    motion:constraintSetStart="@+id/start"
    motion:constraintSetEnd="@+id/right">
    <OnSwipe
        motion:touchAnchorId="@id/view"
        motion:dragDirection="dragRight" />
</Transition>

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

</ConstraintSet>

<ConstraintSet android:id="@+id/left">

    <Constraint
        android:id="@+id/view"
        android:layout_width="64dp"
        android:layout_height="64dp"

        motion:layout_constraintStart_toStartOf="parent"
        motion:layout_constraintLeft_toLeftOf="parent"
        motion:layout_constraintTop_toTopOf="parent"
        motion:layout_constraintBottom_toBottomOf="parent"/>

</ConstraintSet>

<ConstraintSet android:id="@+id/right">

    <Constraint
        android:id="@+id/view"
        android:layout_width="64dp"
        android:layout_height="64dp"
        motion:layout_constraintEnd_toEndOf="parent"
        motion:layout_constraintRight_toRightOf="parent"

        motion:layout_constraintTop_toTopOf="parent"
        motion:layout_constraintBottom_toBottomOf="parent"/>

</ConstraintSet>

If I call

     onAttachedToWindow() {
    super.onAttachedToWindow();
     
    motionLayout.setTransition(R.id.sRight);
    motionLayout.getTransition(R.id.sLeft).setEnable(false);
}

I can only swipe right

The only other problem is if you are in the "left" state you are you are stuck