SlideShare a Scribd company logo
1 of 133
Download to read offline
@mikescamell
Do the Loco-MotionLayout
@mikescamell
HERE!!!
@mikescamell
by Nikita Duhovny 
– Nicolas Roard
“A mix between the property animation framework, layout transitions
with TransitionManager, and CoordinatorLayout”
MotionLayout
@mikescamellScene 1 - Part 1
@mikescamellScene 1 - Part 1
<ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/bookCover"
android:layout_width="wrap_content"
android:layout_height="300dp"
android:adjustViewBounds="true"
android:elevation="4dp"
android:outlineProvider="bounds"
android:src="@drawable/nolongerhuman"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3" />
</ConstraintLayout>
@mikescamellScene 1 - Part 1
@mikescamell
(Yes yes yes I know!)
dependencies {
  implementation 'com.android.support.constraint:constraint-layout:2.0.0-alpha3'
}
@mikescamellScene 1 - Part 2
<ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/bookCover"
android:layout_width="wrap_content"
android:layout_height="300dp"
android:adjustViewBounds="true"
android:elevation="4dp"
android:outlineProvider="bounds"
android:src="@drawable/nolongerhuman"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3" />
</ConstraintLayout>
@mikescamellScene 1 - Part 2
<MotionLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/bookCover"
android:layout_width="wrap_content"
android:layout_height="300dp"
android:adjustViewBounds="true"
android:elevation="4dp"
android:outlineProvider="bounds"
android:src="@drawable/nolongerhuman"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3" />
</MotionLayout>
@mikescamell
2019-03-20 19:45:26.529 28239-28239/? E/MotionLayout: WARNING NO app:layoutDescription tag
2019-03-20 19:45:26.683 28239-28239/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mikescamell.locomotionlayout, PID: 28239
java.lang.NullPointerException: Attempt to invoke virtual method 'int
androidx.constraintlayout.motion.widget.MotionScene.getDuration()' on a null object
reference
Scene 1 - Part 2
@mikescamell
@mikescamellScene 1 - Part 2
<MotionScene>
</MotionScene>
@mikescamellScene 1 - Part 2
<MotionScene>
<Transition
android:id="@+id/startToEnd"
app:constraintSetStart="@+id/start"
app:constraintSetEnd="@+id/end">
</Transition>
</MotionScene>
@mikescamell
<MotionScene>
<Transition
android:id="@+id/startToEnd"
app:constraintSetStart="@+id/start"
app:constraintSetEnd="@+id/end">
<OnSwipe
app:dragDirection="dragDown"
app:touchAnchorId="@id/bookCover"
app:touchAnchorSide="bottom" />
</Transition>
</MotionScene>
Scene 1 - Part 2
@mikescamellScene 1 - Part 2
@mikescamellScene 1 - Part 2
<MotionScene>
<Transition
android:id="@+id/startToEnd"
app:constraintSetStart="@+id/start"
app:constraintSetEnd="@+id/end">
<OnSwipe
app:dragDirection="dragDown"
app:touchAnchorId="@id/bookCover"
app:touchAnchorSide="bottom" />
</Transition>
</MotionScene>
@mikescamell
<MotionScene>
...
</MotionScene>
Scene 1 - Part 2
@mikescamell
<MotionScene>
...
<ConstraintSet android:id="@+id/start">
</ConstraintSet>
</MotionScene>
Scene 1 - Part 2
@mikescamellScene 1 - Part 2
<MotionScene>
...
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@+id/bookCover">
<Layout
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3"
app:layout_height="300dp"
app:layout_width="wrap_content" />
<Transform
app:rotationX="0"
app:translationY="0dp" />
</Constraint>
</ConstraintSet>
…
</MotionScene>
@mikescamellScene 1 - Part 2
<MotionScene>
...
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@+id/bookCover">
<Layout
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3"
app:layout_height="300dp"
app:layout_width="wrap_content" />
<Transform
app:rotationX="0"
app:translationY="0dp" />
</Constraint>
</ConstraintSet>
</MotionScene>
@mikescamellScene 1 - Part 2
<MotionScene>
...
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@+id/bookCover">
<Layout
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3"
app:layout_height="300dp"
app:layout_width="wrap_content" />
<Transform
app:rotationX="0"
app:translationY="0dp" />
</Constraint>
</ConstraintSet>
</MotionScene>
@mikescamellScene 1 - Part 2
<MotionScene>
...
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@+id/bookCover">
<Layout
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3"
app:layout_height="300dp"
app:layout_width="wrap_content" />
<Transform
app:rotationX="0"
app:translationY="0dp" />
</Constraint>
</ConstraintSet>
</MotionScene>
@mikescamellScene 1 - Part 2
<MotionScene>
...
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@+id/bookCover">
<Transform
app:rotationX="0"
app:translationY="0dp" />
</Constraint>
</ConstraintSet>
</MotionScene>
@mikescamell
<MotionScene>
...
<ConstraintSet android:id="@+id/end">
<Constraint android:id="@+id/bookCover">
<Layout
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf=“parent"
app:layout_height="wrap_content"
app:layout_width="150dp" />
<Transform
app:rotationX="-55">
</Constraint>
</ConstraintSet>
</MotionScene>
Scene 1 - Part 2
@mikescamellScene 1 - Part 2
@mikescamellScene 1 - Part 3
@mikescamellScene 1 - Part 3
<MotionLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/scene1_part3">
<ImageView
android:id="@+id/bookCover"
android:layout_width="wrap_content"
android:layout_height="300dp"
android:adjustViewBounds="true"
android:contentDescription="@string/bookcover"
android:elevation="4dp"
android:src="@drawable/nolongerhuman" />
</MotionLayout>
@mikescamell
<MotionLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/scene1_part3">
<MaterialCardView
android:id="@+id/bookSynopsisCard"
android:layout_width="140dp"
android:layout_height="140dp"
app:cardBackgroundColor="@color/crazyPink"
app:cardCornerRadius=“16dp" />
<ImageView … />
</MotionLayout>
Scene 1 - Part 3
@mikescamell
<MotionScene>
…
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@+id/bookSynopsisCard">
<Layout
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.35"
app:layout_height="140dp"
app:layout_width="140dp" />
<Transform app:rotationX="-55" />
</Constraint>
…
</ConstraintSet>
…
</MotionScene>
Scene 1 - Part 3
@mikescamell
<MotionScene>
…
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@+id/bookSynopsisCard">
<Layout
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.35"
app:layout_height="140dp"
app:layout_width="140dp" />
<Transform app:rotationX="-55" />
</Constraint>
…
</ConstraintSet>
…
</MotionScene>
Scene 1 - Part 3
@mikescamell
<MotionScene>
…
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@+id/bookSynopsisCard">
<Layout
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.35"
app:layout_height="140dp"
app:layout_width="140dp" />
<Transform app:rotationX="-55" />
</Constraint>
…
</ConstraintSet>
…
</MotionScene>
Scene 1 - Part 3
@mikescamell
<MotionScene>
…
<ConstraintSet android:id="@+id/end">
<Constraint android:id="@+id/bookSynopsisCard">
<Layout
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3"
app:layout_height="300dp"
app:layout_width="300dp" />
<Transform app:rotationX="0" />
</Constraint>
…
</ConstraintSet>
</MotionScene>
Scene 1 - Part 3
@mikescamell
<MotionScene>
…
<ConstraintSet android:id="@+id/end">
<Constraint android:id="@+id/bookSynopsisCard">
<Layout
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3"
app:layout_height="300dp"
app:layout_width="300dp" />
<Transform app:rotationX="0" />
</Constraint>
…
</ConstraintSet>
</MotionScene>
Scene 1 - Part 3
@mikescamell
<MotionScene>
…
<ConstraintSet android:id="@+id/end">
<Constraint android:id="@+id/bookSynopsisCard">
<Layout
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3"
app:layout_height="300dp"
app:layout_width="300dp" />
<Transform app:rotationX="0" />
</Constraint>
…
</ConstraintSet>
</MotionScene>
Scene 1 - Part 3
@mikescamell
<MotionScene>
…
<ConstraintSet android:id="@+id/end">
<Constraint android:id="@+id/bookCover">
<Layout
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bookSynopsisCard"
app:layout_height="wrap_content"
app:layout_width="150dp" />
<Transform
app:rotationX="-55"
app:translationY="-24dp" />
</Constraint>
</ConstraintSet>
</MotionScene>
Scene 1 - Part 3
@mikescamell
<MotionScene>
…
<ConstraintSet android:id="@+id/end">
<Constraint android:id="@+id/bookCover">
<Layout
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bookSynopsisCard"
app:layout_height="wrap_content"
app:layout_width="150dp" />
<Transform
app:rotationX="-55"
app:translationY="-24dp" />
</Constraint>
</ConstraintSet>
</MotionScene>
Scene 1 - Part 3
@mikescamellScene 1 - Part 3
@mikescamellScene 1 - Part 3
@mikescamellScene 1 - Part 4
@mikescamellScene 1 - Part 4
@mikescamellScene 1 - Part 5
@mikescamellScene 1 - Part 6
@mikescamellScene 1 - Part 6
• KeyAttribute
• KeyPosition
• KeyCycle
• KeyTimeCycle
• KeyTrigger
KeyFrames
@mikescamell
<MotionScene>
<Transition ...>
<KeyFrameSet>
<KeyAttribute
android:alpha="0"
app:framePosition="70"
app:target="@id/bookSynopsisTitle" />
<KeyAttribute
android:alpha="0"
app:framePosition="70"
app:target="@id/bookSynopsisText" />
</KeyFrameSet>
</Transition>
...
</MotionScene>
Scene 1 - Part 6
@mikescamell
Frame 0 Frame 100Frame 70
Synopsis
Scene 1 - Part 6
@mikescamellScene 1 - Part 6
@mikescamellScene 1 - Part 7
Liquidy background
Liquidy background
@mikescamellScene 1 - Part 7
@mikescamellScene 1 - Part 7
shapeshifter.design
@mikescamell
topLeftAnimationForward ?.registerAnimationCallback(object :
Animatable2Compat.AnimationCallback() {
override fun onAnimationEnd(drawable: Drawable?) {
topLeftImageView.setImageDrawable(topLeftAnimationReverse)
topLeftAnimationReverse ?.start()
}
})
Scene 1 - Part 7
topLeftAnimationReverse ?.registerAnimationCallback(object :
Animatable2Compat.AnimationCallback() {
override fun onAnimationEnd(drawable: Drawable?) {
topLeftImageView.setImageDrawable(topLeftAnimationForward)
topLeftAnimationForward ?.start()
}
})
@mikescamellScene 1 - Part 7
@mikescamellScene 2 - Part 1
@mikescamellScene 2 - Part 1
@mikescamellScene 2 - Part 1
@mikescamell
<MotionScene>
...
<ConstraintSet android:id="@+id/end">
<Constraint android:id="@+id/bookSynopsisCard">
<Layout
app:layout_constraintDimensionRatio="16:9"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_height="0dp"
app:layout_width="0dp" />
<Transform app:elevation="8dp" />
</Constraint>
</ConstraintSet>
</MotionScene>
Scene 2 - Part 1
@mikescamellScene 2 - Part 1
@mikescamell
<MotionScene>
...
<ConstraintSet android:id="@+id/end">
<Constraint android:id="@+id/bookSynopsisCard">
<Layout
app:layout_constraintDimensionRatio="16:9"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_height="0dp"
app:layout_width="0dp" />
<Transform app:elevation="8dp" />
</Constraint>
</ConstraintSet>
</MotionScene>
Scene 2 - Part 1
@mikescamell
<MotionScene>
...
<ConstraintSet android:id="@+id/end">
<Constraint android:id="@+id/bookSynopsisCard">
<Layout
app:layout_constraintDimensionRatio="16:9"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_height="0dp"
app:layout_width="0dp" />
<CustomAttribute
app:attributeName="radius"
app:customDimension="0dp" />
<Transform app:elevation="8dp" />
</Constraint>
</ConstraintSet>
</MotionScene>
Scene 2 - Part 1
@mikescamell
• Color
• Integer
• Float
• String
• Dimension
• Boolean
CustomAttribute
Scene 2 - Part 1
@mikescamell
<MotionScene>
...
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@+id/bookSynopsisCard">
<Layout… />
<Transform app:elevation="4dp" />
</Constraint>
</ConstraintSet>
...
</MotionScene>
Scene 2 - Part 1
@mikescamell
<MotionScene>
...
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@+id/bookSynopsisCard">
<Layout… />
<CustomAttribute
app:attributeName="radius"
app:customDimension="16dp" />
<Transform app:elevation="4dp" />
</Constraint>
</ConstraintSet>
...
</MotionScene>
Scene 2 - Part 1
@mikescamell
<MotionScene>
...
<ConstraintSet android:id="@+id/end">
<Constraint android:id="@+id/bookSynopsisCard">
<Layout ... />
<Transform app:elevation="8dp" />
</Constraint>
</ConstraintSet>
</MotionScene>
Scene 2 - Part 1
@mikescamell
<MotionScene>
...
<ConstraintSet android:id="@+id/end">
<Constraint android:id="@+id/bookSynopsisCard">
<Layout ... />
<CustomAttribute
app:attributeName="radius"
app:customDimension="0dp" />
<Transform app:elevation="8dp" />
</Constraint>
</ConstraintSet>
</MotionScene>
Scene 2 - Part 1
@mikescamellScene 2 - Part 1
@mikescamellScene 2 - Part 2
@mikescamell
<MotionScene>
...
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@+id/bookCover">
<Layout
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/bookSynopsisCard"
app:layout_width="150dp" />
<Transform
app:rotationX="-55"
app:translationY="-24dp" />
</Constraint>
</ConstraintSet>
...
</MotionScene>
Scene 2 - Part 2
@mikescamell
<MotionScene>
...
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@+id/bookCover">
<Layout
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/bookSynopsisCard"
app:layout_width="150dp" />
<Transform
app:elevation="4dp"
app:rotationX="-55"
app:translationY="-24dp" />
</Constraint>
</ConstraintSet>
...
</MotionScene>
Scene 2 - Part 2
@mikescamell
<MotionScene>
...
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@+id/bookCover">
<Layout ... />
<Transform ... />
</Constraint>
</ConstraintSet>
...
</MotionScene>
Scene 2 - Part 2
@mikescamell
<MotionScene>
...
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@+id/bookCover">
<Layout ... />
<Transform ... />
<CustomAttribute
app:attributeName="outlineSpotShadowColor"
app:customColorValue="@color/transparent" />
</Constraint>
</ConstraintSet>
...
</MotionScene>
Scene 2 - Part 2
@mikescamellScene 2 - Part 2
<MotionScene>
...
<ConstraintSet android:id=“@+id/end">
<Constraint android:id="@+id/bookCover">
<Layout ... />
<Transform
app:elevation="12dp"
app:rotationX="0"
app:translationY="24dp" />
<CustomAttribute
app:attributeName="outlineSpotShadowColor"
app:customColorValue=“@color/black" />
</Constraint>
</ConstraintSet>
...
</MotionScene>
@mikescamellScene 2 - Part 2
<MotionScene>
...
<ConstraintSet android:id=“@+id/end">
<Constraint android:id="@+id/bookCover">
<Layout ... />
<Transform
app:elevation="12dp"
app:rotationX="0"
app:translationY="24dp" />
<CustomAttribute
app:attributeName="outlineSpotShadowColor"
app:customColorValue=“@color/black" />
</Constraint>
</ConstraintSet>
...
</MotionScene>
@mikescamellScene 2 - Part 2
<MotionScene>
...
<ConstraintSet android:id=“@+id/end">
<Constraint android:id="@+id/bookCover">
<Layout ... />
<Transform
app:elevation="12dp"
app:rotationX="0"
app:translationY="24dp" />
<CustomAttribute
app:attributeName="outlineSpotShadowColor"
app:customColorValue=“@color/black" />
</Constraint>
</ConstraintSet>
...
</MotionScene>
@mikescamellScene 2 - Part 2
@mikescamellScene 2 - Part 3
@mikescamell
KEYATTRIBUTES
Scene 2 - Part 3
@mikescamell
<MotionScene>
<Transition ...>
<OnClick ... />
</Transition>
...
</MotionScene>
Scene 2 - Part 3
@mikescamell
<MotionScene>
<Transition ...>
<OnClick ... />
<KeyFrameSet>
<KeyAttribute
android:alpha="0"
app:framePosition="10"
app:target="@id/bookSynopsisTitle" />
<KeyAttribute
android:alpha="0"
app:framePosition="10"
app:target="@id/bookSynopsisText" />
</KeyFrameSet>
</Transition>
...
</MotionScene>
Scene 2 - Part 3
@mikescamell
<MotionScene>
<ConstraintSet android:id="@+id/start">
...
<Constraint android:id="@+id/bookSynopsisTitle">
<Transform app:elevation="4dp" />
<PropertySet app:alpha="1" />
</Constraint>
<Constraint android:id="@+id/bookSynopsisText">
<Transform app:elevation="4dp" />
<PropertySet app:alpha="1" />
</Constraint>
...
</ConstraintSet>
...
</MotionScene>
Scene 2 - Part 3
@mikescamell
<MotionScene>
...
<ConstraintSet android:id="@+id/end">
<Constraint android:id="@+id/bookSynopsisTitle">
<Transform app:elevation="8dp" />
<PropertySet app:alpha="0" />
</Constraint>
<Constraint android:id="@+id/bookSynopsisText">
<Transform app:elevation="8dp" />
<PropertySet app:alpha="0" />
</Constraint>
...
</ConstraintSet>
</MotionScene>
Scene 2 - Part 3
@mikescamellScene 2 - Part 3
@mikescamellScene 2 - Part 4
@mikescamellScene 2 - Part 4
<MotionLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/bookType"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginEnd="16dp"
android:elevation="8dp"
android:fontFamily="@font/lora_italic"
android:text="@string/novel"
android:textSize="12sp"
android:translationY="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bookCover"
app:layout_constraintTop_toTopOf="@+id/bookCover" />
</MotionLayout>
@mikescamellScene 2 - Part 4
<MotionLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/bookType"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginEnd="16dp"
android:elevation="8dp"
android:fontFamily="@font/lora_italic"
android:text="@string/novel"
android:textSize="12sp"
android:translationY="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bookCover"
app:layout_constraintTop_toTopOf="@+id/bookCover" />
</MotionLayout>
@mikescamell
<MotionScene>
<Transition ...>
<OnClick ... />
<KeyFrameSet>
<KeyAttribute
android:alpha="0"
app:framePosition="95"
app:target="@id/bookType" />
...
</KeyFrameSet>
</Transition>
...
</MotionScene>
Scene 2 - Part 4
@mikescamell
<MotionScene>
<Transition ...>
<OnClick ... />
<KeyFrameSet>
<KeyAttribute
android:alpha="0"
app:framePosition="95"
app:target="@id/bookType" />
...
</KeyFrameSet>
</Transition>
...
</MotionScene>
Scene 2 - Part 4
@mikescamellScene 2 - Part 4
@mikescamell
motionLayout.setTransitionListener(object : MotionLayout.TransitionListener {
override fun onTransitionTrigger(
motionLayout: MotionLayout, startId: Int, endId: Boolean, progress: Float
) {
}
override fun onTransitionStarted(
motionLayout: MotionLayout, startId: Int, endId: Int
) {
}
override fun onTransitionChange(
motionLayout: MotionLayout, startId: Int, endId: Int, progress: Float
) {
}
override fun onTransitionCompleted(motionLayout: MotionLayout, currentId: Int) {
}
})
Scene 2 - Part 4
@mikescamell
motionLayout.setTransitionListener(object : MotionLayout.TransitionListener {
...
override fun onTransitionChange(
motionLayout: MotionLayout, startId: Int, endId: Int, progress: Float
) {
}
...
})
Scene 2 - Part 4
@mikescamell
motionLayout.setTransitionListener(object : MotionLayout.TransitionListener {
...
override fun onTransitionChange(
motionLayout: MotionLayout, startId: Int, endId: Int, progress: Float
) {
val color =
ColorUtils.setAlphaComponent(Color.WHITE, calculateProgressAlpha(progress))
bottomRightAnimationForward ?.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
bottomRightAnimationReverse ?.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
}
...
})
Scene 2 - Part 4
@mikescamellScene 2 - Part 4
@mikescamellScene 2 - Part 5
@mikescamell
<ConstraintSet android:id="@+id/start">
...
<Constraint android:id="@+id/favourite">
<PropertySet app:alpha="0" />
</Constraint>
<Constraint android:id="@+id/bookmark">
<PropertySet app:alpha="0" />
</Constraint>
<Constraint android:id="@+id/readButton">
<PropertySet app:alpha="0" />
</Constraint>
</ConstraintSet>
Scene 2 - Part 5
@mikescamell
<MotionScene>
<Transition ...>
<OnClick ... />
<KeyFrameSet>
...
<KeyAttribute
android:alpha="0"
app:framePosition="80"
app:target="@id/favourite" />
<KeyAttribute
android:alpha="0"
app:framePosition="85"
app:target="@id/bookmark" />
<KeyAttribute
android:alpha="0"
app:framePosition="90"
app:target="@id/readButton" />
</KeyFrameSet>
</Transition>
</MotionScene>
Scene 2 - Part 5
@mikescamell
<MotionScene>
<Transition ...>
<OnClick ... />
<KeyFrameSet>
...
<KeyAttribute
android:alpha="0"
app:framePosition="80"
app:target="@id/favourite" />
<KeyAttribute
android:alpha="0"
app:framePosition="85"
app:target="@id/bookmark" />
<KeyAttribute
android:alpha="0"
app:framePosition="90"
app:target="@id/readButton" />
</KeyFrameSet>
</Transition>
</MotionScene>
Scene 2 - Part 5
@mikescamell
<MotionScene>
<Transition ...>
<OnClick ... />
<KeyFrameSet>
...
<KeyAttribute
android:alpha="0"
app:framePosition="80"
app:target="@id/favourite" />
<KeyAttribute
android:alpha="0"
app:framePosition="85"
app:target="@id/bookmark" />
<KeyAttribute
android:alpha="0"
app:framePosition="90"
app:target="@id/readButton" />
</KeyFrameSet>
</Transition>
</MotionScene>
Scene 2 - Part 5
@mikescamellScene 2 - Part 5
@mikescamellScene 2 - Part 5
@mikescamellScene 2 - Part 6
@mikescamell
<MotionLayout
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:motionDebug="SHOW_PATH"
app:layoutDescription="@xml/scene2_part5">
Scene 2 - Part 6
@mikescamell
<MotionLayout
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:motionDebug="SHOW_PROGRESS"
app:layoutDescription="@xml/scene2_part5">
Scene 2 - Part 6
@mikescamellScene 2 - Part 6
<KeyPosition />
@mikescamellScene 2 - Part 6
<KeyPosition
app:curveFit="linear" />
@mikescamellScene 2 - Part 6
<KeyPosition
app:curveFit="linear"
app:framePosition="0" />
@mikescamellScene 2 - Part 6
<KeyPosition
app:curveFit="linear"
app:framePosition="0"
app:keyPositionType="deltaRelative"
app:percentX="1" />
@mikescamellScene 2 - Part 6
Start Position
End Position
X
Y
1.0
1.0
Delta Relative
@mikescamellScene 2 - Part 6
X
Y
1.0
1.0
End Position
Start Position
Parent Relative
@mikescamellScene 2 - Part 6
X
Y
1.0
1.0
End Position
Start Position
Path Relative
@mikescamellScene 2 - Part 6
Start Position
End Position
X
Y
1.0
1.0
Delta Relative
@mikescamellScene 2 - Part 6
Start Position
End Position
X
Y
1.0
1.0
2.0
Delta Relative
@mikescamellScene 2 - Part 6
<KeyPosition
app:curveFit="linear"
app:framePosition="0"
app:keyPositionType="deltaRelative"
app:percentX="1" />
@mikescamellScene 2 - Part 6
<KeyPosition
app:curveFit="linear"
app:framePosition="0"
app:keyPositionType="deltaRelative"
app:percentX="1"
app:target="@+id/favourite" />
@mikescamellScene 2 - Part 6
<KeyPosition
app:curveFit="linear"
app:framePosition="0"
app:keyPositionType="deltaRelative"
app:percentX="1"
app:target="@+id/favourite"
app:transitionEasing="decelerate" />
@mikescamellScene 2 - Part 6
@mikescamell
<MotionScene>
<Transition ...>
<KeyFrameSet>
<KeyAttribute
android:alpha="0"
android:translationY="24dp"
app:framePosition="80"
app:target="@id/favourite" />
...
</KeyFrameSet>
</Transition>
...
</MotionScene>
Scene 2 - Part 6
@mikescamellScene 2 - Part 6
@mikescamellScene 2 - Part 7
@mikescamellScene 2 - Part 7
<MotionScene>
<ConstraintSet android:id="@+id/start">
...
<Constraint android:id="@+id/bookDetailScrollView">
<PropertySet app:alpha="0" />
<Layout
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent" />
</Constraint>
</ConstraintSet>
...
</MotionScene>
@mikescamellScene 2 - Part 7
<MotionScene>
...
<ConstraintSet android:id="@+id/end">
...
<Constraint android:id="@+id/bookDetailScrollView">
<PropertySet app:alpha="1" />
<Layout
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf=“@id/bookCover“ />
</Constraint>
</ConstraintSet>
</MotionScene>
@mikescamell
<MotionScene>
<Transition ...>
<KeyFrameSet>
<KeyAttribute
android:alpha="0"
app:framePosition="50"
app:target="@id/bookDetailScrollView" />
...
</KeyFrameSet>
</Transition>
...
</MotionScene>
Scene 2 - Part 7
@mikescamellScene 2 - Part 7
@mikescamell
<MotionScene>
<Transition
android:id="@+id/startToMiddle"
app:constraintSetEnd="@+id/middle"
app:constraintSetStart="@+id/start"
app:duration="1000">
<OnClick
app:clickAction="toggle"
app:target="@id/bookCover" />
<KeyFrameSet ... />
</Transition>
...
<ConstraintSet android:id="@+id/start" ... />
<ConstraintSet android:id="@+id/middle" ... />
<ConstraintSet android:id=“@+id/end" ... />
</MotionScene>
Combined Scene - Part 1,2,3
@mikescamell
<MotionScene>
...
<Transition
android:id="@+id/middleToEnd"
app:constraintSetEnd="@+id/end"
app:constraintSetStart="@+id/middle"
app:duration="1000">
<OnClick
app:clickAction="toggle"
app:target="@id/bookSynopsisCard" />
<KeyFrameSet ... />
</Transition>
<ConstraintSet android:id="@+id/start" ... />
<ConstraintSet android:id="@+id/middle" ... />
<ConstraintSet android:id=“@+id/end" ... />
</MotionScene>
Combined Scene - Part 1,2,3
@mikescamell
Considerations
• No GUI (in progress)
• Doesn’t work with RecyclerViews (likely in alpha04)
• It’s in alpha!
• Performance?
• Elevation shadow tweaking is only 28+
• Difficult to have multiple transitions using same target
@mikescamell
@mikescamell
Considerations
• No GUI (in progress)
• Doesn’t work with RecyclerViews (coming soon )
• It’s in alpha!
• Performance?
• Elevation shadow tweaking is only 28+
• Difficult to have multiple transitions using same target
@mikescamell
Summary
• Start out simple
• Use an empty project
• Read the blog posts & ask questions! #motionlayout
• Take advantage of Apply Changes
• HAVE FUN!
@mikescamell
But wait…
@mikescamell
@mikescamell
MWUHAHAHAHAHA
HAHAHAHAHAHAH
AHAHAHHAHAHAH
AHAHAHAHAHAHA
HAHAHAHAHAHAH
AHAHAHAHAHA!!!!!
L
O
L
O
L
O
L
O
L
O
L
O
L
O
L
@johnhoford
@mikescamell
THANK YOU!
Want to read the latest blog posts from Android Developers around
the world? Checkout:
androiddev.io
(please it’s costing me $5 a month)
Twitter: @mikescamell
Website: mikescamell.com
Podcast (on hiatus): androidsnacks.com
(Skip to the “funny” bits at the end)
Slides:
@mikescamell
Links
• Slides
- TODO
• Loco-MotionLayout Repo
- https://github.com/mikescamell/Loco-MotionLayout
• Nicolas Roard’s MotionLayout Series:
- https://medium.com/google-developers/introduction-to-motionlayout-part-i-29208674b10d
- https://medium.com/google-developers/introduction-to-motionlayout-part-ii-a31acc084f59
- https://medium.com/google-developers/introduction-to-motionlayout-part-iii-47cd64d51a5
- https://medium.com/google-developers/defining-motion-paths-in-motionlayout-6095b874d37
• Google Constraint/MotionLayout Example Repo
- https://github.com/googlesamples/android-ConstraintLayoutExamples
@mikescamell
Links
• MotionLayout Sunday 🎉 ™ (where the idea for this talk originated):
- https://twitter.com/MikeScamell/status/1071810532888457217
- https://twitter.com/MikeScamell/status/1074342193102495746
- https://twitter.com/MikeScamell/status/1076790689659322368
- https://twitter.com/MikeScamell/status/1079508256857436160
- https://twitter.com/MikeScamell/status/1082037771362029574
• ShapeShifter (Creating AnimatedVectorDrawables)
- https://shapeshifter.design/
• PorterDuff.Mode
- https://developer.android.com/reference/android/graphics/PorterDuff.Mode
@mikescamell
• TODO add more videos
• Check for todo slides

More Related Content

Similar to Do the Loco-MotionLayout: Building animations with MotionLayout

Android Material Design APIs/Tips
Android Material Design APIs/TipsAndroid Material Design APIs/Tips
Android Material Design APIs/TipsKen Yee
 
Fragments: Why, How, What For?
Fragments: Why, How, What For?Fragments: Why, How, What For?
Fragments: Why, How, What For?Brenda Cook
 
Data binding 入門淺談
Data binding 入門淺談Data binding 入門淺談
Data binding 入門淺談awonwon
 
Beauty Treatment for your Android Application
Beauty Treatment for your Android ApplicationBeauty Treatment for your Android Application
Beauty Treatment for your Android ApplicationCodemotion
 
Android 2D Drawing and Animation Framework
Android 2D Drawing and Animation FrameworkAndroid 2D Drawing and Animation Framework
Android 2D Drawing and Animation FrameworkJussi Pohjolainen
 
How to use data binding in android
How to use data binding in androidHow to use data binding in android
How to use data binding in androidInnovationM
 
Android JetPack: easy navigation with the new Navigation Controller
Android JetPack: easy navigation with the new Navigation ControllerAndroid JetPack: easy navigation with the new Navigation Controller
Android JetPack: easy navigation with the new Navigation ControllerLeonardo Pirro
 
Mobile First Responsive Design
Mobile First Responsive DesignMobile First Responsive Design
Mobile First Responsive DesignJason Grigsby
 
Design Patterns for Tablets and Smartphones
Design Patterns for Tablets and SmartphonesDesign Patterns for Tablets and Smartphones
Design Patterns for Tablets and SmartphonesMichael Galpin
 
Pinkoi Mobile Web
Pinkoi Mobile WebPinkoi Mobile Web
Pinkoi Mobile Webmikeleeme
 
Support Design Library
Support Design LibrarySupport Design Library
Support Design LibraryTaeho Kim
 
Eye candy for your iPhone
Eye candy for your iPhoneEye candy for your iPhone
Eye candy for your iPhoneBrian Shim
 
Android Layout
Android LayoutAndroid Layout
Android Layoutmcanotes
 
Building responsive web mobile mapping applications
Building responsive web mobile mapping applicationsBuilding responsive web mobile mapping applications
Building responsive web mobile mapping applicationsAllan Laframboise
 
Building iPad apps with Flex - 360Flex
Building iPad apps with Flex - 360FlexBuilding iPad apps with Flex - 360Flex
Building iPad apps with Flex - 360Flexdanielwanja
 
Responsive websites. Toolbox
Responsive websites. ToolboxResponsive websites. Toolbox
Responsive websites. ToolboxWojtek Zając
 
Make your app dance with MotionLayout
Make your app dance with MotionLayoutMake your app dance with MotionLayout
Make your app dance with MotionLayouttimmy80713
 
Web mapping with vector data. Is it the future ? 2012
Web mapping with vector data. Is it the future ? 2012Web mapping with vector data. Is it the future ? 2012
Web mapping with vector data. Is it the future ? 2012Moullet
 

Similar to Do the Loco-MotionLayout: Building animations with MotionLayout (20)

Chapter 5 - Layouts
Chapter 5 - LayoutsChapter 5 - Layouts
Chapter 5 - Layouts
 
Android Material Design APIs/Tips
Android Material Design APIs/TipsAndroid Material Design APIs/Tips
Android Material Design APIs/Tips
 
Fragments: Why, How, What For?
Fragments: Why, How, What For?Fragments: Why, How, What For?
Fragments: Why, How, What For?
 
Data binding 入門淺談
Data binding 入門淺談Data binding 入門淺談
Data binding 入門淺談
 
1. shared pref
1. shared pref1. shared pref
1. shared pref
 
Beauty Treatment for your Android Application
Beauty Treatment for your Android ApplicationBeauty Treatment for your Android Application
Beauty Treatment for your Android Application
 
Android 2D Drawing and Animation Framework
Android 2D Drawing and Animation FrameworkAndroid 2D Drawing and Animation Framework
Android 2D Drawing and Animation Framework
 
How to use data binding in android
How to use data binding in androidHow to use data binding in android
How to use data binding in android
 
Android JetPack: easy navigation with the new Navigation Controller
Android JetPack: easy navigation with the new Navigation ControllerAndroid JetPack: easy navigation with the new Navigation Controller
Android JetPack: easy navigation with the new Navigation Controller
 
Mobile First Responsive Design
Mobile First Responsive DesignMobile First Responsive Design
Mobile First Responsive Design
 
Design Patterns for Tablets and Smartphones
Design Patterns for Tablets and SmartphonesDesign Patterns for Tablets and Smartphones
Design Patterns for Tablets and Smartphones
 
Pinkoi Mobile Web
Pinkoi Mobile WebPinkoi Mobile Web
Pinkoi Mobile Web
 
Support Design Library
Support Design LibrarySupport Design Library
Support Design Library
 
Eye candy for your iPhone
Eye candy for your iPhoneEye candy for your iPhone
Eye candy for your iPhone
 
Android Layout
Android LayoutAndroid Layout
Android Layout
 
Building responsive web mobile mapping applications
Building responsive web mobile mapping applicationsBuilding responsive web mobile mapping applications
Building responsive web mobile mapping applications
 
Building iPad apps with Flex - 360Flex
Building iPad apps with Flex - 360FlexBuilding iPad apps with Flex - 360Flex
Building iPad apps with Flex - 360Flex
 
Responsive websites. Toolbox
Responsive websites. ToolboxResponsive websites. Toolbox
Responsive websites. Toolbox
 
Make your app dance with MotionLayout
Make your app dance with MotionLayoutMake your app dance with MotionLayout
Make your app dance with MotionLayout
 
Web mapping with vector data. Is it the future ? 2012
Web mapping with vector data. Is it the future ? 2012Web mapping with vector data. Is it the future ? 2012
Web mapping with vector data. Is it the future ? 2012
 

Recently uploaded

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceanilsa9823
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 

Recently uploaded (20)

Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 

Do the Loco-MotionLayout: Building animations with MotionLayout