Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Motion Layout : Make your apps move auto-magically

Motion Layout : Make your apps move auto-magically

Motion Layout is introduced in ConstraintLayout 2.0 and it gives a lot of flexibility to make animations and transitions.

Lin Min Phyo

July 09, 2019
Tweet

More Decks by Lin Min Phyo

Other Decks in Programming

Transcript

  1. Motion Layout :
    Make your apps move auto-magically
    @Linminphyoe1

    View Slide

  2. About the talk
    • A walkthrough to sample app
    • Strategy for building an
    interactive animations easily
    • Learning approaches to

    Motion Layout
    • Tips and tricks

    View Slide

  3. Who am I ?
    Lin Min Phyo
    Senior Android Developer
    Product, UI/UX, Software Architectures

    View Slide

  4. Motion Layout
    Make your apps move auto-magically

    View Slide

  5. Motion Layout
    class MotionLayout extends ConstraintLayout

    View Slide

  6. Back to the past

    View Slide

  7. Before Constraint Layout
    Building UI is hard

    View Slide

  8. • Nested Hierarchy
    • Non-functional Design
    View
    • Not Flexible
    Before Constraint Layout

    View Slide

  9. Constraint Layout 1.x
    Which problems are solved?

    View Slide

  10. Constraint Layout 1.x
    Flatter Hierarchy

    View Slide

  11. Constraint Layout 1.x
    Flatter Hierarchy

    View Slide

  12. Constraint Layout 1.x
    • Easy positioning views

    • Guidelines

    • Chains

    • Bias

    • Many utilities and
    functionalities
    Features Highlights
    https://developer.android.com/reference/android/support/constraint/ConstraintLayout

    View Slide

  13. Constraint Layout 1.x
    How?

    View Slide

  14. Constraint Layout 1.x
    • Connections between views

    • Connections between view
    and parent view group

    • Connections between view
    and helper views
    Constraints

    View Slide

  15. Constraints

    A

    View Slide

  16. Constraints


    A B

    View Slide

  17. Constraints


    A B

    View Slide

  18. Constraints

    app:layout_constraintStart_toEndOf=“@+id/A” />
    A B

    View Slide

  19. Constraints

    A

    View Slide

  20. Constraints


    B
    A

    View Slide

  21. Constraints


    B
    A

    View Slide

  22. Constraints
    A
    B

    app:layout_constraintStart_toStartOf=“@+id/A” />

    View Slide

  23. Constraints
    app:layout_constraintStart_toStartOf=“parent” />
    B

    View Slide

  24. Constraints

    View Slide

  25. Guidelines
    android:layout_width="wrap_content"
    android:layout_height=“wrap_content”
    />

    View Slide

  26. Guidelines
    android:layout_width="wrap_content"
    android:layout_height=“wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent=“.30”
    />

    View Slide

  27. Guidelines
    android:layout_width="wrap_content"
    android:layout_height=“wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent=“.60”
    />

    View Slide

  28. Guidelines
    android:layout_width="wrap_content"
    android:layout_height=“wrap_content"
    android:orientation=“horizontal"
    app:layout_constraintGuide_percent=“.40”
    />

    View Slide

  29. Transitions
    How transitions work

    View Slide

  30. How transitions work

    View Slide

  31. Start State End State
    Transition
    How transitions work

    View Slide

  32. How transitions work
    Start State End State
    Transition

    View Slide

  33. Constraint Sets
    Made animation easy

    View Slide

  34. state_one.xml
    Constraint Sets

    View Slide

  35. state_one.xml state_two.xml
    Constraint Sets

    View Slide

  36. Constraint Sets
    Activity.kt

    View Slide

  37. Constraint Sets
    ConstraintSet constraintSet1 = new ConstraintSet();
    ConstraintSet constraintSet2 = new ConstraintSet();
    Activity.kt

    View Slide

  38. Constraint Sets
    ConstraintSet constraintSet1 = new ConstraintSet();
    ConstraintSet constraintSet2 = new ConstraintSet();
    constraintSet1.clone(context, R.layout.state_one);
    constraintSet2.clone(context, R.layout.state_two);
    Activity.kt

    View Slide

  39. Constraint Sets
    ConstraintSet constraintSet1 = new ConstraintSet();
    ConstraintSet constraintSet2 = new ConstraintSet();
    constraintSet1.clone(context, R.layout.state_one);
    constraintSet2.clone(context, R.layout.state_two);
    poster.setOnClickListener {
    if (nowAtStateTwo) {
    constraintSet1.applyTo(contentView);
    } else {
    constraintSet2.applyTo(contentView);
    }
    }
    Activity.kt

    View Slide

  40. Constraint Sets
    ConstraintSet constraintSet1 = new ConstraintSet();
    ConstraintSet constraintSet2 = new ConstraintSet();
    constraintSet1.clone(context, R.layout.state_one);
    constraintSet2.clone(context, R.layout.state_two);
    TransitionManager.beginDelayedTransition(contentView);
    poster.setOnClickListener {
    if (nowAtStateTwo) {
    constraintSet1.applyTo(contentView);
    } else {
    constraintSet2.applyTo(contentView);
    }
    }
    Activity.kt

    View Slide

  41. Constraint Layout 2.x
    More goodness

    View Slide

  42. Constraint Layout 2.x
    • Linear helper
    • Flow
    • ImageFilterView
    • Layer
    • Mock View
    • Decorators
    • Motion Layout
    Official docs @ https://developer.android.com/reference/android/support/constraint/classes

    View Slide

  43. Motion Layout
    One layout to rule them all

    View Slide

  44. Motion Layout
    class MotionLayout extends ConstraintLayout

    View Slide

  45. @layout/state_one.xml
    @layout/state_two.xml
    package/activity.kt
    Constraint Sets Motion Layout
    @layout/layout.xml
    VS

    View Slide

  46. @layout/state_one.xml
    @layout/state_two.xml
    package/activity.kt
    Constraint Sets Motion Layout
    @layout/layout.xml
    VS
    Views of the layout

    View Slide

  47. @layout/state_one.xml
    @layout/state_two.xml
    package/activity.kt
    Constraint Sets Motion Layout
    @layout/layout.xml
    @xml/motion.xml
    VS
    View attributes and transitions

    View Slide

  48. @layout/state_one.xml
    @layout/state_two.xml
    package/activity.kt
    Constraint Sets Motion Layout
    @layout/layout.xml
    @layout/motion.xml
    package/activity.kt
    VS
    [ Optional ]

    View Slide

  49. Sample App

    View Slide

  50. Movie Poster
    @layout/layout_poster.xml
    @xml/motion_poster.xml

    View Slide

  51. android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/motion_poster">

    @layout/layout_poster.xml

    View Slide

  52. android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/motion_poster">

    @layout/layout_poster.xml

    View Slide

  53. android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/motion_poster">

    @layout/layout_poster.xml

    View Slide

  54. android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/motion_poster">
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/card_movie_poster"
    app:layout_constraintDimensionRatio="2:3"
    >
    android:id="@+id/image_poster"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scaleType="centerCrop"
    android:src="@drawable/poster_endgame"
    />


    @layout/layout_poster.xml

    View Slide

  55. android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/motion_poster">
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/card_movie_poster"
    app:layout_constraintDimensionRatio="2:3"
    >
    android:id="@+id/image_poster"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scaleType="centerCrop"
    android:src="@drawable/poster_endgame"
    />


    @layout/layout_poster.xml

    View Slide

  56. android:layout_height="match_parent"
    android:scaleType="centerCrop"
    android:src="@drawable/poster_endgame"
    />

    android:id="@+id/guideline_horizontal_10"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintGuide_percent=".10"/>
    android:id="@+id/guideline_vertical_52"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent=".52"/>
    android:id="@+id/guideline_vertical_48"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent=“.48"/>

    @layout/layout_poster.xml

    View Slide

  57. android:layout_height="match_parent"
    android:scaleType="centerCrop"
    android:src="@drawable/poster_endgame"
    />

    android:id="@+id/guideline_horizontal_10"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintGuide_percent=".10"/>
    android:id="@+id/guideline_vertical_52"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent=".52"/>
    android:id="@+id/guideline_vertical_48"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent=“.48"/>

    @layout/layout_poster.xml

    View Slide

  58. android:layout_height="match_parent"
    android:scaleType="centerCrop"
    android:src="@drawable/poster_endgame"
    />

    android:id="@+id/guideline_horizontal_10"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintGuide_percent=".10"/>
    android:id="@+id/guideline_vertical_52"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent=".52"/>
    android:id="@+id/guideline_vertical_48"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent=“.48"/>

    @layout/layout_poster.xml

    View Slide

  59. Movie Poster
    @layout/layout_poster.xml
    @xml/motion_poster.xml

    View Slide

  60. Movie Poster

    @layout/layout_poster.xml
    @xml/motion_poster.xml

    View Slide

  61. @xml/motion_poster.xml

    View Slide

  62. @xml/motion_poster.xml
    Start State End State
    Transition

    View Slide

  63. Start State
    @xml/motion_poster.xml


    View Slide

  64. MotionScene
    XML for holding views’ attributes and transitions

    View Slide

  65. MotionScene


    (Optional)

    View Slide

  66. MotionScene


    (Optional)
    Hold view attributes

    View Slide

  67. MotionScene


    (Optional)
    Define start frame, end frame and transition information

    View Slide

  68. MotionScene


    (Optional)
    Group of states defined for different screens

    View Slide

  69. Start State
    @xml/motion_poster.xml


    View Slide

  70. Start State
    @xml/motion_poster.xml

    android:id="@+id/frame_poster_top">


    View Slide

  71. Start State
    @xml/motion_poster.xml

    android:id="@+id/frame_poster_top">




    View Slide

  72. Constraints
    Attributes of a view

    View Slide

  73. Constraint Attributes
    Layout
    Transform
    Property
    Motion
    CustomAttribute

    View Slide

  74. Constraint Attributes
    Layout
    Transform
    Property
    Motion
    CustomAttribute
    View Positioning Attributes

    View Slide

  75. Constraint Attributes
    Layout
    Transform
    Property
    Motion
    CustomAttribute
    Rotations, re-sizings, translation

    View Slide

  76. Constraint Attributes
    Layout
    Transform
    Property
    Motion
    CustomAttribute
    Alpha, Visibility

    View Slide

  77. Constraint Attributes
    Layout
    Transform
    Property
    Motion
    CustomAttribute
    Path Rotation, Easing

    View Slide

  78. Constraint Attributes
    Layout
    Transform
    Property
    Motion
    CustomAttribute
    View attributes with reflection

    View Slide

  79. Start State
    @xml/motion_poster.xml

    android:id="@+id/frame_poster_top">




    View Slide

  80. Start State
    @xml/motion_poster.xml

    android:id="@+id/frame_poster_top">

    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginStart=“24dp”
    app:layout_constraintDimensionRatio=“2:3"
    app:layout_constraintStart_toStartOf=“parent"
    app:layout_constraintEnd_toStartOf=“@+id/guide_y_52"
    app:layout_constraintTop_toTopOf=“@+id/guide_x_10”/>



    View Slide

  81. @xml/motion_poster.xml
    Start State End State
    Transition

    View Slide


  82. android:id=“@+id/frame_poster_top">

    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginStart="24dp"
    app:layout_constraintDimensionRatio=“2:3"
    app:layout_constraintStart_toStartOf=“parent"
    app:layout_constraintEnd_toStartOf="@+id/guide_y_52"
    app:layout_constraintTop_toTopOf=“@+id/guide_x_10”/>



    End State
    @xml/motion_poster.xml

    View Slide

  83. android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginStart="24dp"
    app:layout_constraintDimensionRatio=“2:3"
    app:layout_constraintStart_toStartOf=“parent"
    app:layout_constraintEnd_toStartOf="@+id/guide_y_52"
    app:layout_constraintTop_toTopOf=“@+id/guide_x_10”/>





    End State
    @xml/motion_poster.xml

    View Slide

  84. android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginStart="24dp"
    app:layout_constraintDimensionRatio=“2:3"
    app:layout_constraintStart_toStartOf=“parent"
    app:layout_constraintEnd_toStartOf=“@+id/guide_y_52"
    app:layout_constraintTop_toTopOf=“@+id/guide_x_10”/>







    End State
    @xml/motion_poster.xml

    View Slide

  85. app:layout_constraintStart_toStartOf=“parent"
    app:layout_constraintEnd_toStartOf=“@+id/guide_y_52"
    app:layout_constraintTop_toTopOf=“@+id/guide_x_10”/>




    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginEnd="24dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintDimensionRatio="2:3"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="@+id/guide_y_48"
    app:layout_constraintTop_toTopOf=“parent"/>



    End State
    @xml/motion_poster.xml

    View Slide

  86. Start State End State
    Transition
    @xml/motion_poster.xml

    View Slide

  87. Transition
    @xml/motion_poster.xml


    •••


    •••


    View Slide

  88. @xml/motion_poster.xml

    android:id=“@+id/transition_poster"
    app:constraintSetStart="@+id/frame_poster_top"
    app:constraintSetEnd=“@+id/frame_poster_middle" >


    •••


    •••


    Transition

    View Slide

  89. Transition
    Describe start frame, end frame and transition
    informations

    View Slide

  90. Transition
    constraintSetStart
    constraintSetEnd
    motionInterpolator
    duration



    View Slide

  91. Transition
    constraintSetStart
    constraintSetEnd
    motionInterpolator
    duration



    View Slide

  92. Transition
    constraintSetStart
    constraintSetEnd
    motionInterpolator
    duration



    View Slide

  93. Transition
    constraintSetStart
    constraintSetEnd
    motionInterpolator
    duration



    Transition easing

    View Slide

  94. Transition
    constraintSetStart
    constraintSetEnd
    motionInterpolator
    duration



    View Slide

  95. Transition
    constraintSetStart
    constraintSetEnd
    motionInterpolator
    duration



    View Slide

  96. Transition
    constraintSetStart
    constraintSetEnd
    motionInterpolator
    duration



    View Slide

  97. Transition
    constraintSetStart
    constraintSetEnd
    motionInterpolator
    duration



    View Slide

  98. @xml/motion_poster.xml

    android:id="@+id/transition_poster"
    app:constraintSetStart="@+id/frame_poster_top"
    app:constraintSetEnd=“@+id/frame_poster_middle" >


    •••


    •••


    Transition

    View Slide

  99. @xml/motion_poster.xml
    Transition

    android:id=“@+id/transition_poster"
    app:constraintSetStart=“@+id/frame_poster_top"
    app:constraintSetEnd=“@+id/frame_poster_middle" >
    app:clickAction="toggle"
    app:targetId=“@+id/card_movie_poster"/>


    •••


    •••


    View Slide

  100. Movie Poster

    @layout/layout_poster.xml
    @xml/motion_poster.xml

    View Slide

  101. Movie Poster


    @layout/layout_poster.xml
    @xml/motion_poster.xml

    View Slide

  102. Yay !!!
    First Version Done

    View Slide

  103. Movie Poster + Movie Information Card
    Add CardView to layout_poster.xml
    Modify motion_poster.xml
    ⚠ Poster’s elevation changed

    View Slide

  104. layout_poster.xml

    View Slide

  105. android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/motion_poster">
    android:id="@+id/card_movie_poster">


    android:id=“@+id/guide_x_10” ••• />
    android:id=“@+id/guide_y_52" ••• />
    android:id=“@+id/guide_y_48” ••• />

    @layout/layout_poster.xml

    View Slide

  106. android:id="@+id/card_movie_poster">


    android:id=“@+id/guide_x_10” ••• />
    android:id=“@+id/guide_y_52" ••• />
    android:id=“@+id/guide_y_48” ••• />
    android:id="@+id/card_movie_info"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:cardElevation="4dp"
    app:layout_constraintDimensionRatio=“1:1"
    />

    @layout/layout_poster.xml

    View Slide

  107. layout_poster.xml

    View Slide

  108. Movie Poster + Movie Information Card
    Add CardView to layout_poster.xml
    Modify @xml/motion_poster.xml

    View Slide

  109. @xml/motion_poster.xml

    View Slide

  110. Start State
    @xml/motion_poster.xml



    •••



    View Slide

  111. Start State
    @xml/motion_poster.xml



    •••



    View Slide

  112. Start State
    @xml/motion_poster.xml



    •••
    app:attributeName="cardElevation"
    app:customDimension=“16dp" />



    View Slide




  113. •••
    app:attributeName="cardElevation"
    app:customDimension=“16dp" />





    Start State
    @xml/motion_poster.xml

    View Slide



  114. app:attributeName="cardElevation"
    app:customDimension=“16dp" />


    android:layout_width="match_parent"
    android:layout_height=“0dp"
    android:layout_marginTop="48dp"
    app:layout_constraintTop_toBottomOf=“@+id/guide_x_10”
    app:layout_constraintBottom_toBottomOf=“parent" />



    Start State
    @xml/motion_poster.xml

    View Slide

  115. @xml/motion_poster.xml
    Start State End State

    View Slide



  116. •••



    •••



    End State
    @xml/motion_poster.xml

    View Slide



  117. •••



    •••



    End State
    @xml/motion_poster.xml

    View Slide



  118. •••



    •••
    app:attributeName="cardElevation"
    app:customDimension=“2dp" />



    End State
    @xml/motion_poster.xml

    View Slide



  119. •••
    app:attributeName="cardElevation"
    app:customDimension=“2dp" />





    End State
    @xml/motion_poster.xml

    View Slide

  120. •••
    app:attributeName="cardElevation"
    app:customDimension=“2dp" />


    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginStart="24dp"
    app:layout_constraintDimensionRatio="1:1"
    app:layout_constraintEnd_toEndOf=“@+id/guide_y_52"
    app:layout_constraintStart_toStartOf=“parent"
    app:layout_constraintTop_toTopOf=“parent"
    app:layout_constraintBottom_toBottomOf="parent"
    />



    End State
    @xml/motion_poster.xml

    View Slide

  121. @xml/motion_poster.xml
    Start State End State

    View Slide

  122. Movie Poster + Movie Information Card
    Add CardView to layout_poster.xml
    Modify @xml/motion_poster.xml


    View Slide

  123. Movie Poster + Movie Information Card
    Expected Result

    View Slide

  124. Movie Poster + Movie Information Card
    Expected Result

    View Slide

  125. KeyFrames to the rescue

    View Slide

  126. KeyFrames
    Start End
    progress = 0 progress = 100

    View Slide

  127. KeyFrames
    Start End
    progress = 0 progress = 100
    KeyFrame
    progress = 50

    View Slide

  128. KeyFrames
    Start End
    progress = 0 progress = 100
    KeyFrame
    progress = 50
    10 20 70

    View Slide

  129. KeyFrames




    View Slide

  130. KeyFrames




    Controls layout position during animation

    View Slide

  131. Controls layout position during animation




    KeyFrames

    View Slide

  132. KeyFrames




    View Slide

  133. KeyFrames




    Controls the post layout properties during animation

    View Slide

  134. KeyFrames




    Controls the post layout properties during animation

    View Slide

  135. KeyFrames




    View Slide

  136. KeyFrames




    Controls oscillations with respect to position of post
    layout properties during animation

    View Slide





  137. Controls oscillations with respect to position of post
    layout properties during animation
    KeyFrames

    View Slide

  138. KeyFrames




    Controls oscillations with respect to position of post
    layout properties during animation

    View Slide

  139. KeyFrames




    View Slide

  140. KeyFrames




    Controls oscillations with respect to time of post layout
    properties during animation

    View Slide

  141. KeyFrames




    Controls oscillations with respect to time of post layout
    properties during animation

    View Slide

  142. KeyFrames




    Controls oscillations with respect to time of post layout
    properties during animation

    View Slide

  143. Add KeyFrames for Poster

    View Slide

  144. Add KeyFrames for Poster
    @xml/motion_poster.xml
    android:id=“@+id/transition_poster"
    app:constraintSetStart=“@+id/frame_poster_top"
    app:constraintSetEnd=“@+id/frame_poster_middle" >
    app:clickAction="toggle"
    app:targetId=“@+id/card_movie_poster"/>

    View Slide

  145. Add KeyFrames for Poster
    @xml/motion_poster.xml
    android:id=“@+id/transition_poster"
    app:constraintSetStart=“@+id/frame_poster_top"
    app:constraintSetEnd=“@+id/frame_poster_middle" >


    app:clickAction="toggle"
    app:targetId=“@+id/card_movie_poster"/>

    View Slide

  146. android:id=“@+id/transition_poster"
    app:constraintSetStart=“@+id/frame_poster_top"
    app:constraintSetEnd=“@+id/frame_poster_middle" >

    app:framePosition="90"
    app:keyPositionType="parentRelative"
    app:motionTarget="@+id/card_movie_poster"
    app:percentX="1"
    app:percentY=".5" />

    app:clickAction="toggle"
    app:targetId=“@+id/card_movie_poster"/>

    Add KeyFrames for Poster
    @xml/motion_poster.xml

    View Slide

  147. Add KeyFrames for Poster
    @xml/motion_poster.xml
    android:id=“@+id/transition_poster"
    app:constraintSetStart=“@+id/frame_poster_top"
    app:constraintSetEnd=“@+id/frame_poster_middle" >

    app:framePosition="90"
    app:keyPositionType="parentRelative"
    app:motionTarget="@+id/card_movie_poster"
    app:percentX="1"
    app:percentY=".5" />
    app:framePosition="90"
    app:keyPositionType="parentRelative"
    app:motionTarget="@+id/card_movie_info"
    app:percentY=".5"
    app:percentX="0" />

    app:clickAction="toggle"
    app:targetId=“@+id/card_movie_poster"/>

    View Slide

  148. Recap

    View Slide

  149. Recap

    app:constraintSetEnd="@+id/frame_poster_middle"
    app:constraintSetStart="@+id/frame_poster_top" >
    •••


    •••


    •••


    View Slide


  150. app:constraintSetEnd="@+id/frame_poster_middle"
    app:constraintSetStart="@+id/frame_poster_top" >
    •••


    •••






    Recap

    View Slide


  151. app:constraintSetEnd="@+id/frame_poster_middle"
    app:constraintSetStart="@+id/frame_poster_top" >
    •••


    •••


    •••


    Recap

    View Slide


  152. app:constraintSetEnd="@+id/frame_poster_middle"
    app:constraintSetStart="@+id/frame_poster_top" >
    •••






    •••


    Recap

    View Slide


  153. app:constraintSetEnd="@+id/frame_poster_middle"
    app:constraintSetStart="@+id/frame_poster_top" >
    •••


    •••


    •••


    Recap

    View Slide


  154. app:constraintSetEnd="@+id/frame_poster_middle"
    app:constraintSetStart="@+id/frame_poster_top" >
    app:clickAction="toggle"
    app:targetId="@+id/card_movie_poster"/>
    •••


    •••


    •••

    Recap

    View Slide


  155. app:constraintSetEnd="@+id/frame_poster_middle"
    app:constraintSetStart="@+id/frame_poster_top" >
    app:clickAction="toggle"
    app:targetId=“@+id/card_movie_poster"/>

    app:framePosition="90"
    app:motionTarget="@+id/card_movie_poster" ••• />
    app:framePosition="90"
    app:motionTarget=“@+id/card_movie_info" ••• />



    •••
    Recap

    View Slide

  156. Movie Informations
    @layout/layout_movie_info.xml
    @motion/motion_movie_info.xml

    View Slide

  157. @layout/layout_movie_info.xml
    Holds 4 TextViews

    View Slide

  158. Movie Informations
    @layout/layout_movie_info.xml
    @motion/motion_movie_info.xml

    View Slide

  159. @motion/motion_movie_info.xml
    Holds 2 ConstraintSets and Transition

    View Slide

  160. Movie Informations
    @layout/layout_movie_info.xml
    @motion/motion_movie_info.xml


    Use KeyFrames to show or hide
    movie summary at the middle

    View Slide

  161. Two Screens

    View Slide

  162. Combine Two Screens
    @layout/movie_poster.xml @layout/movie_info.xml

    View Slide

  163. Combine Two Screens


    @layout/movie_poster.xml @layout/movie_info.xml

    View Slide

  164. Combine Two Screens



    @layout/movie_poster.xml @layout/movie_info.xml

    View Slide

  165. motionLayoutPoster.setTransitionListener( )
    Combine Two Screens
    Passing progress to child layout
    PosterActivity.kt

    View Slide

  166. motionLayoutPoster.setTransitionListener(object : TransitionListener {
    override fun onTransitionChange(
    motionLayout: MotionLayout?,
    startState: Int,
    endState: Int,
    progress: Float
    ) {
    }
    • • •
    })
    Combine Two Screens
    Passing progress to child layout
    PosterActivity.kt

    View Slide

  167. motionLayoutPoster.setTransitionListener(object : TransitionListener {
    override fun onTransitionChange(
    motionLayout: MotionLayout?,
    startState: Int,
    endState: Int,
    progress: Float
    ) {
    }
    • • •
    })
    Combine Two Screens
    Passing progress to child layout
    PosterActivity.kt

    View Slide

  168. motionLayoutPoster.setTransitionListener(object : TransitionListener {
    override fun onTransitionChange(
    motionLayout: MotionLayout?,
    startState: Int,
    endState: Int,
    progress: Float
    ) {
    motionLayoutMovieInfo.progress = progress
    }
    • • •
    })
    Combine Two Screens
    Passing progress to child layout
    PosterActivity.kt

    View Slide

  169. After Combining Two Screens

    View Slide

  170. More Movies

    View Slide

  171. Card for More Movies
    Add CardView to layout_poster.xml
    + Modify motion_poster.xml

    View Slide

  172. Card for More Movies
    Start State End State

    View Slide

  173. Card for More Movies
    Start State End State

    View Slide

  174. android:id=“@+id/frame_poster_top">

    ...


    ...


    @xml/motion_poster.xml
    Start State

    View Slide

  175. android:id=“@+id/frame_poster_top">

    ...


    ...


    @xml/motion_poster.xml

    View Slide

  176. android:id="@+id/frame_poster_top">

    ...


    ...


    android:layout_width="400dp"
    android:layout_height="128dp"
    app:layout_constraintTop_toTopOf=“@+id/guide_x_93"
    app:layout_constraintStart_toStartOf=“@+id/guide_y_60”
    />


    @xml/motion_poster.xml

    View Slide

  177. Card for More Movies
    Start State End State

    View Slide

  178. android:id=“@+id/frame_more_movies_expanded">

    @xml/motion_poster.xml
    End State

    View Slide

  179. app:deriveConstraintsFrom="@+id/frame_poster_top"
    android:id="@+id/frame_more_movies_expanded">

    @xml/motion_poster.xml
    End State

    View Slide

  180. app:deriveConstraintsFrom="@+id/frame_poster_top"
    android:id=“@+id/frame_more_movies_expanded">



    @xml/motion_poster.xml
    End State

    View Slide

  181. app:deriveConstraintsFrom="@+id/frame_poster_top"
    android:id=“@+id/frame_more_movies_expanded">

    app:layout_constraintBottom_toBottomOf="parent"
    android:layout_width="match_parent"
    android:layout_height="224dp"
    />


    @xml/motion_poster.xml
    End State

    View Slide

  182. android:id="@+id/transition_more_movies"
    app:constraintSetEnd="@+id/frame_more_movies_expanded"
    app:constraintSetStart=“@+id/frame_poster_top">

    @xml/motion_poster.xml
    End State

    View Slide

  183. android:id="@+id/transition_more_movies"
    app:constraintSetEnd="@+id/frame_more_movies_expanded"
    app:constraintSetStart=“@+id/frame_poster_top">
    app:dragDirection="dragUp"
    app:touchRegionId="@+id/card_more_movies"
    app:touchAnchorId=“@+id/card_more_movies"/>

    @xml/motion_poster.xml
    Transition

    View Slide

  184. Card for More Movies

    View Slide

  185. Add CardView to layout_poster.xml
    + Modify motion_poster.xml
    Card for More Movies

    View Slide

  186. Add CardView to layout_poster.xml
    + Modify motion_poster.xml
    Card for More Movies

    Also add a view with
    opacity transition
    for background dimming

    View Slide

  187. More Movies
    @layout/layout_more_movies.xml
    @motion/motion_more_movies.xml

    View Slide

  188. @layout/layout_more_movies.xml
    •••/>
    ••• />
    android:id="@+id/rv_more_movies"
    ••• />

    View Slide

  189. More Movies
    @layout/layout_more_movies.xml
    @motion/motion_more_movies.xml

    View Slide

  190. @motion/motion_more_movies.xml
    more_movies_expanded
    [ End State ]

    View Slide

  191. @motion/motion_more_movies.xml
    more_movies_collapsed
    more_movies_expanded

    android:id="@+id/transition" />
    android:id="@+id/more_movies_collapsed" />
    android:id="@+id/more_movies_expanded" />

    [ End State ]
    [ Start State ]

    View Slide

  192. More Movies
    @layout/layout_more_movies.xml
    @motion/motion_more_movies.xml


    View Slide

  193. Combine More Movies to UI
    @layout/layout_poster.xml @layout/layout_more_movies.xml

    View Slide

  194. Combine more movies
    @layout/layout_poster.xml
    android:id="@+id/card_more_movies" >


    View Slide

  195. motionLayoutPoster.setTransitionListener(object : TransitionListener {
    override fun onTransitionChange(
    motionLayout: MotionLayout?,
    startState: Int,
    endState: Int,
    progress: Float
    ) {
    • • •
    if(motionLayout?.startState == R.id.frame_poster_top &&
    motionLayout.endState == R.id.frame_more_movies_expanded){
    }
    }
    • • •
    })
    Combine more movies
    Passing progress to child layout
    PosterActivity.kt

    View Slide

  196. motionLayoutPoster.setTransitionListener(object : TransitionListener {
    override fun onTransitionChange(
    motionLayout: MotionLayout?,
    startState: Int,
    endState: Int,
    progress: Float
    ) {
    • • •
    if(motionLayout?.startState == R.id.frame_poster_top &&
    motionLayout.endState == R.id.frame_more_movies_expanded){
    motion_layout_more_movies.progress = progress
    }
    }
    • • •
    })
    Combine more movies
    Passing progress to child layout
    PosterActivity.kt

    View Slide

  197. Finished : More Movies

    View Slide

  198. Recap
    @layout/layout_movie_info.xml
    @xml/motion_movie_info.xml
    @layout/layout_more_movies.xml
    @xml/motion_more_movies.xml
    @layout/layout_poster.xml
    @xml/motion_poster.xml

    View Slide

  199. @layout/layout_movie_info.xml
    @xml/motion_movie_info.xml
    @layout/layout_more_movies.xml
    @xml/motion_more_movies.xml
    @layout/layout_poster.xml
    @xml/motion_poster.xml
    Recap

    View Slide

  200. @layout/layout_movie_info.xml
    @xml/motion_movie_info.xml
    @layout/layout_more_movies.xml
    @xml/motion_more_movies.xml
    @layout/layout_poster.xml
    @xml/motion_poster.xml
    Recap

    View Slide

  201. @xml/motion_poster.xml
    Transition Transition
    State State State

    View Slide

  202. View Slide

  203. Some Examples
    By @chrisbanes

    View Slide

  204. Some Examples
    By @johnhoford

    View Slide

  205. Some Examples
    By @MikeScamell

    View Slide

  206. Tips #1
    Debugging Motion Layout

    View Slide

  207. Tips #1
    Debugging Motion Layout

    View Slide

  208. Tips #2
    Slow down transition

    View Slide

  209. Tips #2
    Slow down transition

    View Slide

  210. Tips #3
    Programatic API

    View Slide

  211. Tips #3
    Programatic API
    https://developer.android.com/reference/android/support/constraint/
    motion/MotionLayout.html#public-methods

    View Slide

  212. 1. Learn Constraint Layout
    2. Find UI inspiration
    3. Make experiments with Motion Layout
    4. Draw your own design [ Optional ]
    5. Add transitions [ Optional ]
    Steps to learn Motion Layout
    Figma Adobe XD
    Adobe XD

    View Slide

  213. Add Motion Layout to the app
    androidx.constraintlayout:constraintlayout:2.0.0-beta2

    View Slide

  214. 1. Define frames, UI components
    2. Define motions
    3. Collaborate with designers
    4. Implement
    5. Polish
    Add Motion Layout to the app

    View Slide

  215. 1. Collapsing Toolbar
    Refactor existing animation to Motion Layout

    View Slide

  216. 1. Collapsing Toolbar
    2. ViewPager
    Refactor existing animation to Motion Layout

    View Slide

  217. 1. Collapsing Toolbar
    2. ViewPager
    3. Gesture based transitions
    Refactor existing animation to Motion Layout

    View Slide

  218. 1. Collapsing Toolbar
    2. ViewPager
    3. Gesture based transitions
    4. Navigation view with

    custom behaviors
    Refactor existing animation to Motion Layout

    View Slide

  219. 1. Collapsing Toolbar
    2. ViewPager
    3. Gesture based transitions
    4. Navigation view with

    custom behaviors
    5. Progress based views
    Refactor existing animation to Motion Layout

    View Slide

  220. The Future
    Motion Layout Editor In Development

    View Slide

  221. Introduction to MotionLayout series
    https:/
    /medium.com/google-developers/introduction-to-motionlayout-part-
    i-29208674b10d
    Official Docs
    https:/
    /developer.android.com/reference/android/support/constraint/motion/
    MotionLayout
    What’s new in ConstraintLayout
    https:/
    /www.youtube.com/watch?v=29gLA90m6Gk
    Official Samples on Github
    https:/
    /github.com/googlesamples/android-ConstraintLayoutExamples
    Learning Resources

    View Slide

  222. Constraint Layout Guide
    https:/
    /constraintlayout.com
    Twitter #motionlayout
    https:/
    /twitter.com/search?q=%23motionlayout
    Optimizing UIs using Constraint Layout (Google I/O extended 2018)
    https:/
    /speakerdeck.com/hashlin/optimizing-uis-using-constraint-layout
    Source codes for this talk
    https:/
    /github.com/hashlin/DroidYangonMoviesApp
    Learning Resources Cont’d

    View Slide

  223. Motion Layout :
    Make your apps move auto-magically
    Q & A
    @Linminphyoe1

    View Slide