Reset or make continuous Motion Layout for counter app

455 Views Asked by At

I am building a counter-based android application using motion layout. I have built this scene using motion layout where you can slide the bead and it'll add +1 to the counter. The initial scene of moving the bead from one place to another on swipe works great but now I don't know how to make the bead start from the initial position it was on and then swipe it to the final position which will then add another +1 to the counter.

I want the process to be continuous as if you're counting on real beads. The code below so far works great. I need help to make the counting process to continue and how to know when that the bead has reached its final position to add +1.

counter_fragment.xml

<?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/tasbeeh_fragment_scene"
    tools:context=".ui.tasbeeh.TasbeehFragment">

    <ImageView
        android:id="@+id/tasbihStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/tasbeeh_start"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/singeBead"
        android:layout_width="45dp"
        android:layout_height="45dp"
        android:layout_marginStart="114dp"
        android:layout_marginTop="71dp"
        android:src="@drawable/singe_bead"
        app:layout_constraintStart_toStartOf="@+id/tasbihStart"
        app:layout_constraintTop_toTopOf="@+id/tasbihStart" />

    <ImageView
        android:id="@+id/tasbihFinal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/tasbeeh_final"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.motion.widget.MotionLayout>

counter_fragment_scene

<?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/start">
        <Constraint android:id="@+id/singeBead"
            android:layout_width="45dp"
            android:layout_height="45dp"
            android:layout_marginStart="114dp"
            android:layout_marginTop="72dp"
            app:layout_constraintStart_toStartOf="@+id/tasbihStart"
            app:layout_constraintTop_toTopOf="@+id/tasbihStart"/>
        <Constraint
            android:id="@+id/tasbihStart"
            app:layout_constraintEnd_toEndOf="parent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
             />
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint android:id="@+id/singeBead"
            android:layout_width="45dp"
            android:layout_height="45dp"
            android:layout_marginStart="231dp"
            android:layout_marginTop="27dp"
            app:layout_constraintStart_toStartOf="@+id/tasbihStart"
            app:layout_constraintTop_toTopOf="@+id/tasbihStart"
            android:layout_marginLeft="232dp" />
        <Constraint
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent"
            android:layout_width="wrap_content"
            android:id="@+id/imageView6"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
             />
        <Constraint
            android:id="@+id/tasbihStart"
            app:layout_constraintEnd_toEndOf="parent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
             />
    </ConstraintSet>

    <Transition
        app:constraintSetStart="@+id/start"
        app:constraintSetEnd="@id/end">
        <OnSwipe
            app:dragDirection="dragRight"
            app:touchAnchorId="@+id/singeBead"/>
    </Transition>
</MotionScene>

Output: https://drive.google.com/file/d/1XR2nE5XZNB7pQHB5nXd7GIBwhRCPQIxs/view?usp=sharing

Expected Output: https://drive.google.com/file/d/1XmcdupU-2Js-rfI_J7Uv_VqvH4Hi6mTk/view?usp=sharing

1

There are 1 best solutions below

0
On BEST ANSWER

You can use a listener :

  motionlayout?.setTransitionListener(object : MotionLayout.TransitionListener {
    override fun onTransitionCompleted(p0: MotionLayout?, currentId: Int) {
            if(currentId == R.id.end){
                 this.counter++
                // run another animation to put singeBead at startpoint   
            }
            else if(currentId == R.id.start){
                this.counter-- 
               // run another animation to put singeBead at startpoint   
            }

        }
       }

And for your counter, you can add a TextView ( for example with id="txt_counter") in your Layout and set :

txt_counter.text = this.counter

It was the solution for the counter. But with the video you send, I think you need 2 images of singleBead. One at the start point and one at the end point. Each has a transition. One for image_start -like you do ) and another one for image_end for with

app:dragDirection="dragLeft"
app:touchAnchorId="+@id/image_end"

After you have to copy/paste what you do for single bead ( start and end constraint) for image_end with different id like start_endpicture and end_endpicture. And you can listening different transition with the listener below. And you really reinitialize the ui state and the counter.