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

ConstraintLayout 2.0

ConstraintLayout 2.0

Presentation of the current state of ConstraintLayout 2.0 library, covering the latest alpha releases (3,4,5) at Android Makers'19

B9012970f22b84c5b344ffa6f8a884d5?s=128

Nicolas Roard

April 23, 2019
Tweet

Transcript

  1. ConstraintLayout 2.0 Nicolas Roard @camaelon John Hoford @johnhoford

  2. Why

  3. ConstraintLayout 1.x Flat hierarchy : decouple layout from the view

    hierarchy Support library Powerful internal engine Design Tools : UI Builder
  4. When : some guidance Simplify layouts of components Build UI

    quickly What about LinearLayout / FrameLayout ?
  5. ConstraintLayout 2.x Flexibility Virtual Layouts Helpers & Decorators Optimizer MotionLayout

    Design Tools : UI Builder, Motion Editor
  6. Motion Editor

  7. Motion Editor

  8. Architecture

  9. Architecture Linear Solver

  10. Architecture Constraints Model Linear Solver

  11. Architecture Linear Solver Constraints Model Optimizer

  12. Architecture Linear Solver Constraints Model Optimizer Virtual Layouts Helpers

  13. Architecture Linear Solver Constraints Model Optimizer MotionLayout Virtual Layouts Helpers

  14. ConstraintLayout

  15. Layout concepts Direct Constraints : relative, circular, dimensions (ratio…) Chains

    Helpers : Guidelines, Barriers, Layer… Decorators Virtual Layout Constraint Sets
  16. Helpers

  17. None
  18. None
  19. None
  20. None
  21. None
  22. None
  23. None
  24. None
  25. Encapsulate Behaviors ConstraintLayout utility Encapsulate a given behavior Apply it

    to a set of widgets ▸ Supported in Studio ▸ Can use View APIs (animation, etc.) in helpers to promote reuse
  26. Circular Reveal

  27. Circular Reveal

  28. @Override public void updatePostLayout(ConstraintLayout container) { super.updatePostLayout(container); if (mContainer !=

    container) { int rad =(int) Math.hypot(mComputedMaxY - mComputedMinY, mComputedMaxX - mComputedMinX); Animator anim = ViewAnimationUtils.createCircularReveal(this, (int) mComputedCenterX-getLeft(), (int) mComputedCenterY-getTop(), 0, rad); anim.setDuration(2000); anim.start(); } mContainer = container; }
  29. @Override public void updatePostLayout(ConstraintLayout container) { super.updatePostLayout(container); if (mContainer !=

    container) { int rad =(int) Math.hypot(mComputedMaxY - mComputedMinY, mComputedMaxX - mComputedMinX); Animator anim = ViewAnimationUtils.createCircularReveal(this, (int) mComputedCenterX-getLeft(), (int) mComputedCenterY-getTop(), 0, rad); anim.setDuration(2000); anim.start(); } mContainer = container; }
  30. <com.example.CircularRevealHelper android:id="@+id/helper" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/lake" app:constraint_referenced_ids="imageView"/>

  31. Decorators

  32. public class MetaballsDecorator extends ConstraintHelper { public void updatePostLayout(ConstraintLayout container)

    { int[] ids = getReferencedIds(); final int count = ids.length; for (int i = 0; i < count; i++) { View view = container.getViewById(ids[i]); // do something } } @Override public void onDraw(Canvas canvas) { // do something } }
  33. Bottom Panel Decorator

  34. Bottom Panel Decorator

  35. Bottom Panel Decorator

  36. Bottom Panel Decorator

  37. Bottom Panel Decorator

  38. Bottom Panel Decorator

  39. Virtual Layouts

  40. MotionLayout

  41. MotionLayout Reflect and animate between multiple states of components Coordinating

    motion of multiple components Support nesting MotionLayout Drive custom views
  42. MotionLayout Reflect and animate between multiple states of components Coordinating

    motion of multiple components Support nesting MotionLayout Drive custom views
  43. MotionLayout Subclass of ConstraintLayout Gets its constraints from a separate

    xml file. Allows you to directly animate between two Constraint sets Extensive control of the Transition between the two Custom attributes — not just layout
  44. Motion concepts States (ConstraintSets) Transitions Keyframes Coordinate Systems OnSwipe/OnClick A

    B
  45. Motion concepts States (ConstraintSets) Transitions Keyframes Coordinate Systems OnSwipe/OnClick A

    B
  46. Motion concepts States (ConstraintSets) Transitions Keyframes Coordinate Systems OnSwipe/OnClick A

    B
  47. States (ConstraintSets) Transitions Keyframes Coordinate Systems OnSwipe/OnClick Motion concepts

  48. States (ConstraintSets) Transitions Keyframes Coordinate Systems OnSwipe/OnClick Motion concepts

  49. States (ConstraintSets) Transitions Keyframes Coordinate Systems OnSwipe/OnClick Motion concepts

  50. States (ConstraintSets) Transitions Keyframes Coordinate Systems OnSwipe/OnClick Motion concepts

  51. Organisation Layout file Views Helpers VirtualLayout MotionScene file OnSwipe Constraint

    KeyFrameSet Transition ConstraintSet
  52. Example

  53. Start & End

  54. Start & End

  55. Positioning <KeyPosition motion:framePosition="50" motion:percentY="0.1" motion:percentX="0.5" motion:keyPositionType="parentRelative" motion:target="@id/sun" motion:pathMotionArc="startHorizontal" />

  56. Positioning <KeyPosition motion:framePosition="50" motion:percentY="0.1" motion:percentX="0.5" motion:keyPositionType="parentRelative" motion:target="@id/sun" motion:pathMotionArc="startHorizontal" />

  57. Custom Attribute : color <KeyAttribute motion:framePosition="25" motion:target="@+id/background"> <CustomAttribute motion:attributeName="background" motion:customColorDrawableValue="#97C0FF"

    </KeyAttribute>
  58. Custom Attribute : color <KeyAttribute motion:framePosition="25" motion:target="@+id/background"> <CustomAttribute motion:attributeName="background" motion:customColorDrawableValue="#97C0FF"

    </KeyAttribute>
  59. Cycles <KeyTimeCycle motion:framePosition="50" android:rotation="45" motion:target="@id/sun" motion:wavePeriod=".5" motion:waveShape="sin" />

  60. Cycles <KeyTimeCycle motion:framePosition="50" android:rotation="45" motion:target="@id/sun" motion:wavePeriod=".5" motion:waveShape="sin" />

  61. How to use it?

  62. Coordinator Layout Collapsible Toolbar From GitHub

  63. Coordinator Layout Collapsible Toolbar From GitHub

  64. DrawerLayout From GitHub

  65. DrawerLayout From GitHub

  66. ViewPager From GitHub

  67. ViewPager From GitHub

  68. Coordination

  69. None
  70. None
  71. From GitHub Nested MotionLayout

  72. From GitHub Nested MotionLayout

  73. Start End MotionLayout 2 MotionLayout 1

  74. Chris Banes "I MotionLayout, creating complex UI animations is a

    breeze when you can define some keyframes and let MotionLayout handle the rest"
  75. Chris Banes "I MotionLayout, creating complex UI animations is a

    breeze when you can define some keyframes and let MotionLayout handle the rest"
  76. None
  77. None
  78. Cycles

  79. None
  80. None
  81. Key Cycles KeyTimeCycles & KeyCycles

  82. Key Cycles KeyTimeCycles & KeyCycles

  83. Key Cycle interpolation <KeyTimeCycle motion:framePosition="34" android:translationX="0dp" motion:target="@id/button" motion:waveOffset="0dp" motion:wavePeriod="2" motion:waveShape="sin"

    />
  84. Monotonic splines • Less prone to overshoot • Needs to

    be differentiable and Integrable Typical Spline Monotonic Spline
  85. KeyCycle •Period - 1/pos across space •Offset - shifts the

    envelope •Attributes - set amplitude of wave
  86. KeyCycles

  87. KeyCycles

  88. KeyCycles Period

  89. KeyCycles Period

  90. KeyCycles Value

  91. KeyCycles Value

  92. KeyCycles offset

  93. KeyCycles offset

  94. KeyCycles waveShape

  95. KeyCycles waveShape

  96. None
  97. None
  98. KeyCycles multiple waves translationX translationY

  99. KeyCycles multiple waves translationX translationY

  100. KeyCycles multiple waves translationX translationY

  101. KeyCycles multiple waves translationX translationY

  102. KeyCycles multiple waves translationX translationY

  103. KeyCycles multiple waves translationX translationY

  104. KeyCycles imagination is the limit translationY rotation translationY rotation

  105. KeyCycles imagination is the limit translationY rotation translationY rotation

  106. Introducing CycleEditor • Explore the capabilities of KeyCycles • XML

    shown compatible with alpha3 • Features: • Graph multiple cycles • Simulate keyCycles effect on a button
  107. KeyTimeCycle •Period - 1/s (Hz) •Offset - shifts the envelope

    •Attributes - set amplitude of wave Same attributes as KeyCycle
  108. KeyTimeCycles Period (Hz) KeyTimeCycle Attribute translationX

  109. KeyTimeCycles Period (Hz) KeyTimeCycle Attribute translationX

  110. KeyTimeCycles (KeyPosition) Change the KeyPosition

  111. KeyTimeCycles (KeyPosition) Change the KeyPosition

  112. KeyTimeCycles (Attribute) Changing value of android:translationX

  113. KeyTimeCycles (Attribute) Changing value of android:translationX

  114. KeyTimeCycles Changing value of motion:waveOffset waveOffset

  115. KeyTimeCycles Changing value of motion:waveOffset waveOffset

  116. KeyTimeCycles Changing value of motion:waveShape

  117. KeyTimeCycles Changing value of motion:waveShape

  118. What’s new

  119. Alpha 3 MotionLayout

  120. alpha 3 New XML format KeyTimeCycle KeyTrigger

  121. Alpha 4 MotionLayout

  122. alpha 4 Richer behaviors for OnClick actions CustomAttributes support for

    customPixelDimensions ImageFilterView overlay support KeyTrigger collision support Attributes rename
  123. MotionLayout Alpha 5

  124. alpha 5 MotionTarget string matching OnSwipe regions Automatic transitions Derived

    ConstraintSets 

  125. Target Matching

  126. MotionTarget matching Two Tags: layout_constraintTag … Label a View motionTarget

    … Takes ID or Regular Expressions Apply one keyframe to many views
  127. layout_constraintTag & motionTarget In Layout… <ImageButtton … motion:layout_constraintTag="ActionRow1" />

  128. layout_constraintTag & motionTarget In Layout… <ImageButtton … motion:layout_constraintTag="ActionRow1" />

  129. layout_constraintTag & motionTarget In Layout… <ImageButtton … motion:layout_constraintTag="ActionRow1" /> Or

    in MotionScene … <ConstraintSet> <Constraint … motion:layout_constraintTag="ActionRow1" /> <Constraint> <PropertySet motion:layout_constraintTag="ActionRow1" /> />
  130. layout_constraintTag & motionTarget In Layout… <ImageButtton … motion:layout_constraintTag="ActionRow1" /> Or

    in MotionScene … <ConstraintSet> <Constraint … motion:layout_constraintTag="ActionRow1" /> <Constraint> <PropertySet motion:layout_constraintTag="ActionRow1" /> /> Now apply in MotionScene <Transition> <KeyPosition … motion:motionTarget="ActionRow1" /> <KeyAttribute … motion:motionTarget=“ActionRow.*” /> />
  131. Region Swipe

  132. <OnSwipe motion:dragDirection="dragUp" motion:touchAnchorId=“@+id/widget" motion:touchAnchorSide=“top" /> Region Swipe Limiting Swipe to

    regions
  133. <OnSwipe motion:dragDirection="dragUp" motion:touchAnchorId=“@+id/widget" motion:touchAnchorSide=“top" /> Region Swipe Limiting Swipe to

    regions
  134. dragDirection dragUp dragDown dragRight dragLeft touchAnchorId touchAnchorSide top bottom left

    right touchRegionId
  135. Example <OnSwipe motion:dragDirection="dragUp" motion:touchAnchorId=“@+id/widget" motion:touchRegionId="@+id/widget" motion:touchAnchorSide=“top" />

  136. Example <OnSwipe motion:dragDirection="dragUp" motion:touchAnchorId=“@+id/widget" motion:touchRegionId="@+id/widget" motion:touchAnchorSide=“top" />

  137. Auto Transition

  138. <Transition motion:constraintSetStart="@+id/a" motion:constraintSetEnd=“@+id/n" motion:duration=“1000"/> Auto Transition A B Transition

  139. <Transition motion:constraintSetStart="@+id/a" motion:constraintSetEnd=“@+id/b" motion:autoTransition="animateToStart" motion:duration=“1000"/> Auto Transition A B Transition

  140. Auto Transition On start animation

  141. Auto Transition On start animation

  142. Auto Transition On start animation START Transition A B Transition

  143. Auto Transition <Transition motion:constraintSetEnd="@+id/end" motion:constraintSetStart=“@+id/start" motion:autoTransition=“jumpToEnd" motion:duration=“1000"> "jumpToStart" "jumpToEnd" "animateToStart"

    "animateToEnd"
  144. Derived Constraints

  145. Derived Constraint <ConstraintSet android:id="@+id/base"> </ConstraintSet> <ConstraintSet android:id="@+id/state1"> <Constraint android:id="@id/view1"> <PropertySet

    motion:visibility=“gone"/> </Constraint> </ConstraintSet> <ConstraintSet android:id=“@+id/state2" motion:deriveConstraintsFrom="@id/state1"> <Constraint android:id="@id/view2"> <PropertySet motion:visibility="gone"/> </Constraint> </ConstraintSet> <ConstraintSet android:id=“@+id/state3" motion:deriveConstraintsFrom="@id/state2"> <Constraint android:id="@id/view3"> <PropertySet motion:visibility="gone"/> </Constraint> </ConstraintSet> Base layout
  146. Derived Constraint <ConstraintSet android:id="@+id/base"> </ConstraintSet> <ConstraintSet android:id="@+id/state1"> <Constraint android:id="@id/view1"> <PropertySet

    motion:visibility=“gone"/> </Constraint> </ConstraintSet> <ConstraintSet android:id=“@+id/state2" motion:deriveConstraintsFrom="@id/state1"> <Constraint android:id="@id/view2"> <PropertySet motion:visibility="gone"/> </Constraint> </ConstraintSet> <ConstraintSet android:id=“@+id/state3" motion:deriveConstraintsFrom="@id/state2"> <Constraint android:id="@id/view3"> <PropertySet motion:visibility="gone"/> </Constraint> </ConstraintSet> Base layout + view1 gone
  147. Derived Constraint <ConstraintSet android:id="@+id/base"> </ConstraintSet> <ConstraintSet android:id="@+id/state1"> <Constraint android:id="@id/view1"> <PropertySet

    motion:visibility=“gone"/> </Constraint> </ConstraintSet> <ConstraintSet android:id=“@+id/state2" motion:deriveConstraintsFrom="@id/state1"> <Constraint android:id="@id/view2"> <PropertySet motion:visibility="gone"/> </Constraint> </ConstraintSet> <ConstraintSet android:id=“@+id/state3" motion:deriveConstraintsFrom="@id/state2"> <Constraint android:id="@id/view3"> <PropertySet motion:visibility="gone"/> </Constraint> </ConstraintSet> Base layout + view1 gone + view2 gone
  148. Derived Constraint <ConstraintSet android:id="@+id/base"> </ConstraintSet> <ConstraintSet android:id="@+id/state1"> <Constraint android:id="@id/view1"> <PropertySet

    motion:visibility=“gone"/> </Constraint> </ConstraintSet> <ConstraintSet android:id=“@+id/state2" motion:deriveConstraintsFrom="@id/state1"> <Constraint android:id="@id/view2"> <PropertySet motion:visibility="gone"/> </Constraint> </ConstraintSet> <ConstraintSet android:id=“@+id/state3" motion:deriveConstraintsFrom="@id/state2"> <Constraint android:id="@id/view3"> <PropertySet motion:visibility="gone"/> </Constraint> </ConstraintSet> Base layout + view1 gone + view2 gone + view3 gone
  149. Virtual Layout Alpha 5

  150. Flow

  151. Flow : Virtual Layout Helper : reference objets Keep a

    Flat Hierarchy On the fly changes
  152. Flow modes 1. Apply an horizontal or vertical chain to

    the elements 2. Wrap elements as needed, using chains 3. Wrap elements as needed, aligning in rows & columns
  153. Flow : a view

  154. Flow : a view Flow is a perfectly normal view

    You can ask it to wrap_content or be of a given size You can set up a background
  155. Flow : XML <android.support.constraint.helper.Flow android:id="@+id/flow" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#F8BA00" android:padding="10dp" app:constraint_referenced_ids="A,B,C"

    app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toTopOf="parent">
  156. Flow : chains

  157. Flow mode : chains A B C Spread

  158. Flow mode : chains A B C Spread Inside

  159. Flow mode : chains A B C Packed

  160. Flow : XML <android.support.constraint.helper.Flow android:id="@+id/flow" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#F8BA00" android:padding="10dp" app:flow_horizontalStyle="packed"

    app:flow_horizontalGap="10dp" app:constraint_referenced_ids="A,B,C" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toTopOf="parent">
  161. Flow : XML <android.support.constraint.helper.Flow android:id="@+id/flow" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#F8BA00" android:padding="10dp" app:flow_horizontalStyle=“spread"

    app:flow_horizontalGap="10dp" app:constraint_referenced_ids="A,B,C" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toTopOf="parent">
  162. Flow : XML <android.support.constraint.helper.Flow android:id="@+id/flow" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#F8BA00" android:padding="10dp" app:flow_horizontalStyle=“spread_inside”

    app:flow_horizontalGap="10dp" app:constraint_referenced_ids="A,B,C" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toTopOf="parent">
  163. Flow : Wrap Chains

  164. Flow mode : wrap chains A B C D E

    F
  165. Flow mode : wrap chains A B C D E

    F
  166. Flow mode : wrap chains A B C D E

    F Wrapping Add a new chain
  167. Flow mode : wrap chains A B C D E

    F Wrapping Spread Chain
  168. Flow mode : wrap chains A B C D E

    F Wrapping Spread Chain Packed Chain
  169. Flow mode : wrap chains A B C D E

    F Wrapping : max elements = 3 (wrap_content)
  170. Flow mode : wrap chains A B C D E

    F No Table?
  171. Flow : Wrap Align

  172. Flow mode : wrap chains A B C D E

    F Wrap : chains
  173. Flow mode : wrap align A B C D E

    F Wrap : Align
  174. Example

  175. Calculator

  176. None
  177. <android.support.constraint.helper.Flow android:id="@+id/flow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#F8BA00" android:padding="20dp" app:constraint_referenced_ids="K7,K8,K9,K4,K5,K6,K1,K2,K3,K0,KDiv,KM,KD" app:flow_horizontalGap="10dp" app:flow_maxElementsWrap="3" app:flow_verticalGap="10dp"

    app:flow_wrapMode=“aligned" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf=“parent" />
  178. <android.support.constraint.helper.Flow android:id="@+id/flow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#F8BA00" android:padding="20dp" app:constraint_referenced_ids="K7,K8,K9,K4,K5,K6,K1,K2,K3,K0,KDiv,KM,KD" app:flow_horizontalGap="10dp" app:flow_maxElementsWrap="3" app:flow_verticalGap="10dp"

    app:flow_wrapMode=“aligned" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf=“parent" />
  179. <android.support.constraint.helper.Flow android:id="@+id/flow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#F8BA00" android:padding="20dp" app:constraint_referenced_ids="K7,K8,K9,K4,K5,K6,K1,K2,K3,K0,KDiv,KM,KD" app:flow_horizontalGap="10dp" app:flow_maxElementsWrap="3" app:flow_verticalGap="10dp"

    app:flow_wrapMode=“aligned" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf=“parent" />
  180. <android.support.constraint.helper.Flow android:id="@+id/flow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#F8BA00" android:padding="20dp" app:constraint_referenced_ids="K7,K8,K9,K4,K5,K6,K1,K2,K3,K0,KDiv,KM,KD" app:flow_horizontalGap="10dp" app:flow_maxElementsWrap="3" app:flow_verticalGap="10dp"

    app:flow_wrapMode=“aligned" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf=“parent" />
  181. None
  182. <TextView android:id="@+id/KR" ... app:layout_constraintBottom_toTopOf="@+id/flow" app:layout_constraintEnd_toEndOf="@+id/flow" app:layout_constraintStart_toStartOf="@+id/flow" />

  183. <TextView android:id="@+id/KE" ... app:layout_constraintEnd_toEndOf=“@+id/KMul" app:layout_constraintStart_toStartOf="@+id/KDiv" app:layout_constraintTop_toBottomOf=“@+id/KMul" />

  184. MotionLayout & Flow

  185. MotionLayout with Flow

  186. MotionLayout with Flow

  187. MotionLayout with Flow

  188. MotionLayout with Flow

  189. RecyclerView + MotionLayout

  190. None
  191. None
  192. None
  193. None
  194. None
  195. None
  196. How it works Handle Gesture Provide a similar view Add

    view to Placeholder in MotionLayout Recompute bounds Run transition
  197. Handling new PlaceholderGestureHandler( motionLayout, recyclerView, view, viewType ) gestureHandler.onTouchEvent(event)

  198. Basic start to end motion

  199. Basic start to end motion

  200. Add size delay <KeyPosition motion:framePosition=“40” motion:percentX=“0” motion:percentWidth=“0” motion:percentHeight=“0” motion:target=“@id/rvItem” />

  201. Add size delay <KeyPosition motion:framePosition=“40” motion:percentX=“0” motion:percentWidth=“0” motion:percentHeight=“0” motion:target=“@id/rvItem” />

  202. Add tilt <KeyAttribute motion:framePosition=“60” motion:rotationX=“-20” motion:target=“@id/rvItem” />

  203. Add tilt <KeyAttribute motion:framePosition=“60” motion:rotationX=“-20” motion:target=“@id/rvItem” />

  204. Wrapping up…

  205. Timeline… Alpha 4 : released April 4th Alpha 5 :

    in the next few days! Beta 1 around Google IO Motion Editor : resume work after Google IO
  206. developer.android.com https://developer.android.com/reference/android/support/constraint/classes.html Medium Articles: Introduction to MotionLayout part I http://bit.ly/2O4AmIz

    Introduction to MotionLayout part II http://bit.ly/2uPuWbw Introduction to MotionLayout part III http://bit.ly/2zRjCSj Introduction to MotionLayout part IV http://bit.ly/2QqfJaF Github: https://github.com/googlesamples/android-ConstraintLayoutExamples Documentation
  207. Give us feedback! http://issuetracker.google.com ConstraintLayout component

  208. Thanks! Nicolas Roard @camaelon John Hoford @johnhoford