Search code examples
androidandroid-layoutandroid-constraintlayoutandroid-motionlayout

Programmatically change ConstraintSet attribute in motion scene of MotionLayout


I have a use case where I want to create Youtube like animation using MotionLayout. There is a sample for this animation in this repo. But the problem is that in this example they use static height for starting constraint like this which is 320dp:

<MotionScene...>

    <Transition..>

        <OnSwipe... />

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

            <Constraint
                android:id="@id/top_image_container"
                android:layout_width="0dp"
                android:layout_height="320dp"
                motion:layout_constraintTop_toTopOf="parent"
                motion:layout_constraintStart_toStartOf="parent"
                motion:layout_constraintEnd_toEndOf="parent"  />

      </ConstraintSet>
  </Transition>
</MotionScene>

But my requirement to set constraint using aspect ratio. For static aspect ratio, I can set using app:layout_constraintDimensionRatio="w,16:9" in Constraint like this.

<Constraint
    android:id="@id/top_image_container"
    android:layout_width="0dp"
    android:layout_height="0dp"
    motion:layout_constraintTop_toTopOf="w,16:9"
    motion:layout_constraintTop_toTopOf="parent"
    motion:layout_constraintStart_toStartOf="parent"
    motion:layout_constraintEnd_toEndOf="parent"  />

But every video has a different aspect ratio which I am getting from API.So I want to set different aspect ratio depending upon the video. I am not able to find a way to set this programmatically in the ConstraintSet

I tried a workaround to set android:layout_height="wrap_content" and change the view aspect ratio programmatically. But it did not work and the animation was not working properly.

Any solution or suggestion would be appreciated.


Solution

  • What you can do is access the ConstraintSet and then set the ratio:

    motionLayout.getConstraintSet(R.id.start)?.let { startConstraintSet ->
        val ratio = imageView.calculateRatio()
        startConstraintSet.setDimensionRatio(R.id.top_image_container, ratio)
        // You can set the width and height here as well
    }