Search code examples
androidanimationpaddingandroid-motionlayout

MotionLayout ignores padding


I'm trying to animate margin, padding and alpha of a textview on swipe. At the start, there is no padding of the textview, alpha is 1. At the end, I want alpha to be 0, padding to be 100dp, 16dp dp margin on the sides, alpha to be 0.5 Everything works, except the padding is not changing. Does MotionLayout support padding? I'm using androidx.constraintlayout:constraintlayout:2.0.0-beta4.

adding more text since SO says that my post looks like is mostly code... adding more text since SO says that my post looks like is mostly code... adding more text since SO says that my post looks like is mostly code...

The layout xml:

    <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:id="@+id/layoutParent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/test">

    <TextView
        android:id="@+id/fakenavigationBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:text="hello world">
    </TextView>
</androidx.constraintlayout.motion.widget.MotionLayout>

The motion scene:

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

    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@id/fakenavigationBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:alpha="1"
            android:padding="100dp"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintStart_toStartOf="parent">
        </Constraint>

    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@id/fakenavigationBar"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginEnd="16dp"
            android:alpha="0.5"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintBottom_toBottomOf="parent">
        </Constraint>

    </ConstraintSet>

    <Transition
        motion:constraintSetStart="@+id/start"
        motion:constraintSetEnd="@+id/end"
        motion:duration="2000"
        motion:motionInterpolator="linear">

        <OnSwipe
            motion:touchAnchorId="@+id/fakenavigationBar"
            motion:touchAnchorSide="top"
            motion:dragDirection="dragDown"/>
    </Transition>
</MotionScene>

enter image description hereenter image description here


Solution

  • This is a limitation of MotionLayout

    Padding is not a supported attribute ConstraintSet and as such does not support it. There are not even methods on View setPaddingTop so they cannot be treated as custom Attributes.

    This is a gap in MotionLayout but there are issues with padding. Padding changes the views measured dimension which request layout as the dimension of the view changes. This is expensive because the only way to resolve the animation is to resolve the starting and ending constraintset and rebuild the interpolation.

    It is best if you redesign you layout to use margins as this is the control of the Layout.