MotionLayout Exploration

Ken Baldauf

Senior Software Engineer @ Originate

Upcoming Meetup Schedule

  • March 25th: Shared Element Transitions
  • April 22nd: Flutter: How to Build a Native Plugin
  • May 27th: Google I/O 2020 Recap

What is MotionLayout?

  • Used to move, resize or animate UI when interacted with
  • Offers a mix of features from:
    • property animation framework
    • TransitionManager
    • CoordinatorLayout
  • Subclass of ConstraintLayout
    • Included in 2.0.0 beta
  • Utilizes new MotionEditor
    • Part of Android Studio 4.0 canary
  • Supports API 14+
  • Only works with direct children
  • Declarative

How does it work?

  • Calculates difference between layout at start & end of animation
  • Layouts & Motion descriptions live in separate files
    • MotionLayout replaces ConstraintLayout in layout file
    • Motion descriptions are in MotionScene XML file
  • MotionScene attached to layout via app:layoutDescription
  • MotionScenes consists of 2 main elements
    • Transition
    • ConstraintSets

Transition

  • Main attributes
    • motion:ConstraintSetStart
    • motion:ConstraintSetEnd
    • motion:duration
  • Child
    • OnSwipe
    • OnClick
    • KeyFrameSet

KeyFrameSet

  • Define middle frames to avoid linear path
  • Each key frame is defined via a KeyPosition
  • framePosition
    • percentage through the animation where frame exists
  • motionTarget
    • view whose path is modified
  • percentX/percentY
    • how much the path is modified
  • keyPositionType
    • determines how percentX/percentY will be used

ConstraintSet

  • MotionScenes consists of two
    • Definition of start state
    • Definition of end state
  • Supports basic position & view attributes
    • alpha
    • visibility
    • elevation
    • rotation, rotationX, rotationY
    • translationX, translationY, translationZ
    • scaleX, scaleY
  •  Custom attributes can define additional attributes
  • Overrides all constraints previously applied to widget

CustomAttributes

  • Specify attributes not built into ConstraintSet
  • motion:attributeName
    • ​string value
    • example: "backgroundColor"
  • Also must include value type attribute
    • motion:customColorValue
    • motion:customIntegerValue
    • motion:customFloatValue
    • motion:customStringValue
    • motion:customDimension
    • motion:customBoolean

Layout

<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/motionLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/scene_01"
    tools:showPaths="true">

    <TextView
        android:id="@+id/helloWorld"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />

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

MotionScene

<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:motion="http://schemas.android.com/apk/res-auto">
  
    <Transition
        motion:constraintSetStart="@+id/start"
        motion:constraintSetEnd="@+id/end"
        motion:duration="1000">
        <OnSwipe
            motion:touchAnchorId="@+id/helloWorld"
            motion:touchAnchorSide="right"
            motion:dragDirection="dragRight" />
    </Transition>
  
    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@+id/helloWorld"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />
    </ConstraintSet>
  
    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@+id/helloWorld"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />
    </ConstraintSet>
</MotionScene>

Questions?

Android MotionLayout

By Kenneth Baldauf

Android MotionLayout

A look into Android's MotionLayout beta.

  • 333