kotlinandroid-motionlayout

Need MotionLayout Reference using DataBinding Tree


I'm trying to get the reference to my MotionLayout inside a Fragment inside my RecyclerView so that I can attach my addTransitionListener. I've got the listener prepared, but I don't know the valid path to this object.

I've seen many great examples that reference motionLayout vars, but I can't seem to get a valid one using DataBinding methods.

My RecyclerView is inside my Fragment as:

<androidx.recyclerview.widget.RecyclerView
                android:id="@+id/shipper_list"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginTop="8dp"
                android:background="@color/mainList"
                tools:listitem="@layout/row_shipper_line"
                />

My MotionLayout is inside my "row_shipper_line" as:

<androidx.constraintlayout.motion.widget.MotionLayout
    android:id="@+id/line_container"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:background="@color/mainList"
    app:layoutDescription="@xml/row_shipper_line_container_scene"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent">

My binding var is set as:

binding = DataBindingUtil.inflate(
            inflater,
            R.layout.create_shipper_fragment,
            container,
            false
        )

I've got this code entered and it compiles, but the events aren't called:

rec = LayoutInflater.from(context).inflate(R.layout.shipper_list, null)

ml = rec.findViewById(R.id.line_container)

var transitionListener = object : MotionLayout.TransitionListener {

     override fun onTransitionStarted(p0: MotionLayout?, startId: Int, endId: Int) {
                Log.d("MyApp", "Transition onTransitionStarted.")
            }

     override fun onTransitionChange(
                p0: MotionLayout?,
                startId: Int,
                endId: Int,
                progress: Float
            ) {
                Log.d("MyApp", "Transition onTransitionChange.")
            }

     override fun onTransitionCompleted(p0: MotionLayout?, currentId: Int) {
                Log.d("MyApp", "Transition onTransitionCompleted.")
            }

      override fun onTransitionTrigger(
                p0: MotionLayout?,
                triggerId: Int,
                positive: Boolean,
                progress: Float
            ) {
                Log.d("MyApp", "Transition onTransitionTrigger.")
            }
        }

 ml.setTransitionListener(transitionListener)

My line swipes LEFT perfectly. I just need to listen for onTransitionComplete.

My binding tree looks like this:

Fragment containing my RecyclerView -> Row Layout containing the MotionLayout tag.

What I'm trying to do is something like this:

binding.shipper_list.line_container

Thank you in advance!


Solution

  • I finally found a solution by experimenting. The key is to place the transition listener inside the list adapter class during onBindViewHolder. Again, this is the only solution I've found if you're using DataBinding inside a Fragment. It immediately works. After further consideration, having this handler inside the list adapter class makes far more sense to keep things encapsulated.

    override fun onBindViewHolder(holder: ShipperViewHolder, position: Int) {
    
        holder.bind(shippers[position])
    
        var ml = holder.itemView.findViewById<MotionLayout>(R.id.uldMotionLayout)
    
        var transitionListener = object : MotionLayout.TransitionListener {
    
            override fun onTransitionStarted(p0: MotionLayout?, startId: Int, endId: Int) {
                Log.d("MyApp", "Transition onTransitionStarted.")
            }
    
            override fun onTransitionChange(
                p0: MotionLayout?,
                startId: Int,
                endId: Int,
                progress: Float
            ) {
                Log.d("MyApp", "Transition onTransitionChange.")
            }
    
            override fun onTransitionCompleted(p0: MotionLayout?, currentId: Int) {
                //viewToVibrate.vibrate()
                Log.d("MyApp", "Transition onTransitionCompleted.")
            }
    
            override fun onTransitionTrigger(
                p0: MotionLayout?,
                triggerId: Int,
                positive: Boolean,
                progress: Float
            ) {
                Log.d("MyApp", "Transition onTransitionTrigger.")
            }
        }
    
        ml.setTransitionListener(transitionListener)
    }