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

ConstraintLayout 2.0 sneak peek

ConstraintLayout 2.0 sneak peek

Presented at AndroidMakers'18

A sneak peek of the ConstraintLayout 2.0 library, presenting some of the new concepts like helpers.

B9012970f22b84c5b344ffa6f8a884d5?s=128

Nicolas Roard

April 23, 2018
Tweet

Transcript

  1. CONSTRAINT LAYOUT 2.0 Nicolas Roard & John Hoford @camaelon @johnhoford

    (Sneak peek)
  2. BUT FIRST…

  3. CL 1.1 1.1

  4. OVERVIEW… goo.gl/txuisJ

  5. CONSTRAINT LAYOUT 1.1 ➤ Circular Constraints ➤ Helper objects ➤

    Optimizer ➤ many bug fixes!
  6. ConstraintLayout 2.0 preview GOOGLE MAVEN REPOSITORY dependencies { compile 'com.android.support.constraint:constraint-layout:1.1.0'

    }
  7. BARRIERS ➤ A barrier takes the minimum or maximum of

    a set of widget ➤ Other widgets can then be constrained to it ➤ Allows to build more flexible layouts Helper object
  8. BARRIERS

  9. BARRIERS

  10. BARRIERS

  11. BARRIERS

  12. BARRIERS

  13. BARRIERS

  14. Barriers

  15. Barriers

  16. Barriers 1 2 3

  17. Barriers 1 2 3 4

  18. Barriers

  19. Barriers

  20. OPTIMIZER ➤ New optimizer in 1.1 ➤ A lot more

    powerful :) ➤ Multiple optimizations passes available ➤ Direct & Center connections ➤ Barriers ➤ Chains (experimental) ➤ Dimensions (experimental)
  21. OPTIMIZER CONSTRAINTS OPTIMIZER SOLVER MEASURES

  22. OPTIMIZER Widget A

  23. OPTIMIZER Widget A

  24. OPTIMIZER Widget A

  25. OPTIMIZER Widget A

  26. OPTIMIZER Widget A Widget B

  27. OPTIMIZER Widget A Widget B

  28. OPTIMIZER Widget A Widget B

  29. OPTIMIZER

  30. OPTIMIZER

  31. OPTIMIZER ➤ Direct ➤ Barriers ➤ Chains (experimental) ➤ Dimensions

    (experimental)
  32. CHAINS OPTIMIZER ➤ Apply if all elements have fixed dimensions

    ➤ Or if all elements are (simple) match_constraint ➤ …more to come
  33. DIMENSIONS OPTIMIZER match_constraint match_constraint 1 match_constraint fixed / wrap_content 2

    fixed / wrap_content fixed / wrap_content 1
  34. DIMENSIONS OPTIMIZER Match_Constraint

  35. ConstraintLayout 2.0 preview OPTIMIZER ATTRIBUTE app:layout_optimizationLevel=“standard” app:layout_optimizationLevel=“direct|barriers|chains|dimensions”

  36. CONSTRAINT LAYOUT 2.0Preview

  37. CL 2.0 WHY?

  38. CL 2.0 UI : RAISING THE BAR

  39. CL 2.0 HELP!

  40. CL 2.0 VOCABULARY

  41. CL 2.0 HELPERS

  42. WHAT’S A HELPER ➤ Not necessarily part of your view

    hierarchy ➤ Helps you specify and build your UI ➤ example: Guideline, Barrier
  43. THREE MAIN CATEGORIES OF HELPERS Layout Manipulation Rendering or Decorating

    Post-Layout Manipulation
  44. CONSTRAINT HELPERS ➤ Keep a reference to existing views ➤

    Flat hierarchy ➤ Views can be referenced by multiple helpers ➤ Essentially, it allows you to tag views, setting specific behaviors
  45. API ➤ Access a list of views ➤ pre/post layouts

    callbacks ➤ normal views ➤ already used ➤ barriers ➤ groups
  46. TOOLING ➤ Integrated manipulation in the component tree (like for

    barriers) ➤ Exposed in the Palette ➤ Support 3rd party libraries ➤ exposing their custom views / helpers
  47. TOOL INTEGRATION

  48. TOOL INTEGRATION

  49. TOOL INTEGRATION

  50. TOOL INTEGRATION

  51. TOOL INTEGRATION

  52. TOOL INTEGRATION

  53. TOOL INTEGRATION

  54. TOOL INTEGRATION

  55. TOOL INTEGRATION

  56. TOOL INTEGRATION

  57. EXAMPLE : COLLECTION HELPER ➤ Trampoline object ➤ forward function

    calls to referenced views ➤ setVisibility ➤ setAlpha ➤ setRotation, etc. ➤ no getter!
  58. CL 2.0 DECORATORS

  59. DECORATORS ➤ Can reference views ➤ Easily build decorators that

    depends on views location / visibility / etc
  60. ConstraintLayout 2.0 preview METABALLS 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 } }
  61. Decorator Canvas ImageViews

  62. Decorator Canvas ImageViews

  63. Decorator Canvas ImageViews

  64. Metaballs Decorator

  65. Metaballs Decorator

  66. Metaballs Decorator

  67. Metaballs Decorator

  68. LAYER DECORATOR ➤ Manipulate graphically a collection of views ➤

    Supports transforms, etc. ➤ Can be set as the bounding box of the referenced views
  69. ConstraintLayout 2.0 preview LET’S CREATE A DRAWABLE… <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">

    <corners android:radius="12dp" /> <stroke android:width="2dp" android:color="@color/colorPrimary" /> <solid android:color="#ffffff" /> </shape
  70. ConstraintLayout 2.0 preview LAYER DECORATOR <android.support.constraint.Layer android:id=“@+id/layer” android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/frame"

    android:padding="32dp" app:constraint_referenced_ids=“button1,button2,button3, button4,button5” />
  71. ConstraintLayout 2.0 preview LAYER DECORATOR <android.support.constraint.Layer android:id=“@+id/layer” android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/frame"

    android:padding="32dp" app:constraint_referenced_ids=“button1,button2,button3, button4,button5” />
  72. ConstraintLayout 2.0 preview LAYER DECORATOR

  73. ConstraintLayout 2.0 preview LAYER DECORATOR

  74. ConstraintLayout 2.0 preview LAYER DECORATOR

  75. ConstraintLayout 2.0 preview LAYER DECORATOR

  76. ConstraintLayout 2.0 preview LAYER DECORATOR

  77. ConstraintLayout 2.0 preview LAYER DECORATOR

  78. ConstraintLayout 2.0 preview LAYERS : PROGRAMMATIC ACCESS Layer layer =

    findViewById(R.id.layer); layer.setRotation(angle); layer.setScaleX(1+(180 - Math.abs(angle-180))/20f); layer.setScaleY(1+(180 - Math.abs(angle-180))/20f); float shift_x = 500 * (float) Math.sin(Math.toRadians(angle*5)); float shift_y = 500 * (float) Math.sin(Math.toRadians(angle*7)); layer.setTranslationX(shift_x); layer.setTranslationY(shift_y);
  79. ConstraintLayout 2.0 preview LAYERS : PROGRAMMATIC ACCESS Layer layer =

    findViewById(R.id.layer); layer.setRotation(angle); layer.setScaleX(1+(180 - Math.abs(angle-180))/20f); layer.setScaleY(1+(180 - Math.abs(angle-180))/20f); float shift_x = 500 * (float) Math.sin(Math.toRadians(angle*5)); float shift_y = 500 * (float) Math.sin(Math.toRadians(angle*7)); layer.setTranslationX(shift_x); layer.setTranslationY(shift_y);
  80. ConstraintLayout 2.0 preview FLY-IN DECORATOR

  81. ConstraintLayout 2.0 preview FLY-IN DECORATOR

  82. ConstraintLayout 2.0 preview FLY-IN DECORATOR

  83. ConstraintLayout 2.0 preview FLY-IN DECORATOR

  84. ConstraintLayout 2.0 preview FLY-IN DECORATOR

  85. ConstraintLayout 2.0 preview FLY-IN DECORATOR

  86. ConstraintLayout 2.0 preview FLY-IN DECORATOR

  87. ConstraintLayout 2.0 preview FLY-IN DECORATOR

  88. ConstraintLayout 2.0 preview FLY IN DECORATOR: XML <com.example.FlyinHelper android:id="@+id/flyinhelper" android:layout_width="match_parent"

    android:layout_height="match_parent" android:background="#F00" app:constraint_referenced_ids=“button1,button2,button3, imageView,button4" />
  89. ConstraintLayout 2.0 preview FLY IN DECORATOR @Override public void updatePostLayout(ConstraintLayout

    container) { update(); } void update(){ if (mContainer == null) { return; } mComputedCenterX = Float.NaN; mComputedCenterY = Float.NaN; View[] views = getViews(mContainer); calcCenters(); float shift = myFlyValue-1; for (int i = 0; i < mCount; i++) { View view = views[i]; int x = (view.getLeft() + view.getRight()) / 2; int y = (view.getTop() + view.getBottom()) / 2; view.setTranslationX((x - mComputedCenterX)*shift); view.setTranslationY((y - mComputedCenterY)*shift); } }
  90. ConstraintLayout 2.0 preview FLY IN DECORATOR @Override public void updatePreLayout(ConstraintLayout

    container) { if (mContainer!=container) { setFlyIn(10); ObjectAnimator.ofFloat(this, "FlyIn", 1f) .setDuration(1000).start(); } mContainer = container; } public void setFlyIn(float flyIn) { myFlyValue = flyIn; update(); }
  91. ConstraintLayout 2.0 preview (BONUS CODE) public void calcCenters() { if

    (!(Float.isNaN(mComputedCenterX) || Float.isNaN(mComputedCenterY))) { return; } if (Float.isNaN(mCenterX) || Float.isNaN(mCenterY)) { int minx = Integer.MAX_VALUE, miny= Integer.MAX_VALUE; int maxx= Integer.MIN_VALUE,maxy= Integer.MIN_VALUE; View []views = getViews(mContainer); for (int i = 0; i < mCount; i++) { View view = views[i]; minx = Math.min(minx, view.getLeft()); miny = Math.min(miny, view.getTop()); maxx = Math.max(maxx, view.getRight()); maxy = Math.max(maxy, view.getBottom()); } mComputedCenterX = (Float.isNaN(mCenterX))?(minx + maxx) / 2:mCenterX; mComputedCenterY = (Float.isNaN(mCenterY))?(miny + maxy) / 2:mCenterY; } else { mComputedCenterY = mCenterY; mComputedCenterX = mCenterX; } }
  92. ConstraintLayout 2.0 preview CIRCULAR REVEAL <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" />
  93. ConstraintLayout 2.0 preview CIRCULAR REVEAL <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" />
  94. ConstraintLayout 2.0 preview CIRCULAR REVEAL <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" />
  95. ConstraintLayout 2.0 preview CIRCULAR REVEAL <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" />
  96. ConstraintLayout 2.0 preview CIRCULAR REVEAL <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" />
  97. ConstraintLayout 2.0 preview CIRCULAR REVEAL <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" />
  98. ConstraintLayout 2.0 preview CIRCULAR REVEAL <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" />
  99. ConstraintLayout 2.0 preview CIRCULAR REVEAL <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" />
  100. ConstraintLayout 2.0 preview CIRCULAR REVEAL <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" />
  101. ConstraintLayout 2.0 preview CIRCULAR REVEAL <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" />
  102. ConstraintLayout 2.0 preview CIRCULAR REVEAL @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; }
  103. ALL TOGETHER…

  104. None
  105. None
  106. None
  107. None
  108. None
  109. None
  110. None
  111. None
  112. None
  113. None
  114. None
  115. None
  116. None
  117. None
  118. None
  119. None
  120. None
  121. None
  122. None
  123. None
  124. None
  125. None
  126. None
  127. None
  128. None
  129. SUMMARY : HELPERS ➤ Tag your views with behavior ➤

    Encapsulate behavior ➤ Declaratively use them ➤ Tool integration
  130. CL 2.0 VIRTUAL LAYOUTS

  131. VIRTUAL LAYOUTS ➤ Layout the referenced views ➤ Still keep

    flat hierarchy ➤ Linear ➤ Flow
  132. LINEAR ➤ Create horizontal or vertical chains ➤ Somewhat similar

    to linear layout, but as a helper
  133. ConstraintLayout 2.0 preview LINEAR <android.support.constraint.Linear android:id=“@+id/linear" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:constraint_referenced_ids="button1,button2,button3"

    app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />
  134. ConstraintLayout 2.0 preview LINEAR

  135. ConstraintLayout 2.0 preview <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="20dp" android:layout_marginTop="20dp" android:text="TextView"

    app:layout_constraintStart_toEndOf="@+id/linear" app:layout_constraintTop_toBottomOf="@+id/linear" />
  136. ConstraintLayout 2.0 preview LINEAR

  137. FLOW ➤ Implements FlexboxLayout-like semantics ➤ Overflow elements will be

    pushed to the next row ➤ Still flat layout! ➤ Able to position outside elements relative to the ones in Flow
  138. ConstraintLayout 2.0 preview FLOW <android.support.constraint.Flow android:id="@+id/flow" app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="8dp" app:constraint_referenced_ids=“button1,button2,button3,button4, button5,button6,button7,button8"

    android:layout_width="match_parent" android:layout_height="wrap_content"/>
  139. ConstraintLayout 2.0 preview REFERENCE OTHER VIEWS <ImageView android:layout_width="200dp" android:layout_height="100dp" android:src="@drawable/background"

    android:scaleType="centerCrop" app:layout_constraintLeft_toLeftOf="@+id/button6" app:layout_constraintTop_toBottomOf="@id/button8"/>
  140. FLOW

  141. ConstraintLayout 2.0 preview FLOW

  142. ConstraintLayout 2.0 preview FLOW

  143. ConstraintLayout 2.0 preview FLOW

  144. ConstraintLayout 2.0 preview FLOW

  145. ConstraintLayout 2.0 preview FLOW

  146. ConstraintLayout 2.0 preview FLOW

  147. CL 2.0 LAYOUT MANAGEMENT

  148. ConstraintLayout 2.0 preview MANAGING STATES

  149. ConstraintLayout 2.0 preview MANAGING STATES

  150. ConstraintLayout 2.0 preview MANAGING STATES

  151. ConstraintLayout 2.0 preview MANAGING STATES

  152. ConstraintLayout 2.0 preview MANAGING STATES

  153. ConstraintLayout 2.0 preview MANAGING STATES

  154. ConstraintLayout 2.0 preview STATE XML <ConstraintLayoutStates> <State android:id="@+id/small" app:constraints=“@layout/layout_small” />

    <State android:id="@+id/large" app:constraints=“@layout/layout_large” /> </ConstraintLayoutStates>
  155. ConstraintLayout 2.0 preview JAVA-SIDE @Override protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState); setContentView(R.layout.layout); cl = findViewById(R.id.root); cl.setLayoutDescription(R.xml.layout_states); }
  156. ConstraintLayout 2.0 preview JAVA-SIDE @Override protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState); setContentView(R.layout.layout); cl = findViewById(R.id.root); cl.setLayoutDescription(R.xml.layout_states); } public void change(View v) { cl.setState(closed ? R.id.large : R.id.small); closed = !closed; }
  157. ConstraintLayout 2.0 preview STATE XML : SIZE QUALIFIERS <ConstraintLayoutStates> <State

    app:constraints=“@layout/layout_small"> <Constraints app:constraints="@layout/layout_small" app:region_widthLessThan="550dp" /> <Constraints app:constraints="@layout/layout_large" app:region_widthMoreThan="450dp"/> </State> </ConstraintLayoutStates>
  158. ConstraintLayout 2.0 preview ON CONFIGURATION CHANGE @Override public void onConfigurationChanged(Configuration

    newConfig) { super.onConfigurationChanged(newConfig); cl.setState(newConfig.screenWidthDp, newConfig.screenHeightDp); }
  159. ConstraintLayout 2.0 preview LIVE RESIZE

  160. ConstraintLayout 2.0 preview LIVE RESIZE

  161. ConstraintLayout 2.0 preview LIVE RESIZE

  162. ConstraintLayout 2.0 preview LIVE RESIZE

  163. ConstraintLayout 2.0 preview LIVE RESIZE

  164. ConstraintLayout 2.0 preview LIVE RESIZE

  165. ConstraintLayout 2.0 preview CALLBACK cl.setOnConstraintsChanged(new ConstraintsChangedListener() { @Override public void

    preLayoutChange(int state,int layoutId) { TransitionManager.beginDelayedTransition(cl); } });
  166. ConstraintLayout 2.0 preview ANIMATED LIVE RESIZE (TRANSITION MANAGER)

  167. ConstraintLayout 2.0 preview ANIMATED LIVE RESIZE (TRANSITION MANAGER)

  168. ConstraintLayout 2.0 preview ANIMATED LIVE RESIZE (TRANSITION MANAGER)

  169. ConstraintLayout 2.0 preview ANIMATED LIVE RESIZE (TRANSITION MANAGER)

  170. ConstraintLayout 2.0 preview ANIMATED LIVE RESIZE (TRANSITION MANAGER)

  171. ConstraintLayout 2.0 preview ANIMATED LIVE RESIZE (TRANSITION MANAGER)

  172. LAYOUT MANAGEMENT ➤ Centralize multiple layouts in a single XML

    ➤ Allows to easily initialize and deal with different representations for your layout ➤ Size qualifiers & live resize
  173. CL 2.0 FLUENT API

  174. FLUENT API ➤ ConstraintSet: great to capture full state and

    manage it ➤ …But not that ideal for direct manipulation ➤ Fluent API to change layout params directly
  175. ConstraintLayout 2.0 preview FLUENT API new Constraints(view).margin(ConstraintProperties.TOP,23).apply(); Constraints.on(view) .margin(TOP, 16)

    .margin(BOTTOM, 16) .margin(LEFT, 16) .margin(RIGHT, 16) .apply(); Constraints.on(view) .center(R.id.button1, LEFT, 23, R.id.button2, RIGHT, 23,.05f) .connect(TOP,PARENT_ID, TOP, 32) .apply();
  176. ConstraintLayout 2.0 preview EXAMPLE : CENTER Constraints.on(myView) .center(R.id.button1, LEFT, R.id.button2,

    RIGHT) .horizontalBias(.5f) .top(PARENT_ID,TOP,32) .apply();
  177. ConstraintLayout 2.0 preview center(int firstID, int firstSide, int firstMargin, int

    secondId, int secondSide, int secondMargin, f centerHorizontally(int leftId, int leftSide, int leftMargin, int rightId, int rightSide, int rightMar centerHorizontallyRtl(int startId, int startSide, int startMargin, int endId, int endSide, int endMar centerVertically(int topId, int topSide, int topMargin, int bottomId, int bottomSide, int bottomMargi centerHorizontally(int toView) centerHorizontallyRtl(int toView) centerVertically(int toView) removeConstraints(int anchor) margin(int anchor, int value) goneMargin(int anchor, int value) horizontalBias(float bias) verticalBias(float bias) dimensionRatio(String ratio) visibility(int visibility) alpha(float alpha) elevation(float elevation) rotation(float rotation) rotationX(float rotationX) rotationY(float rotationY) scaleX(float scaleX) scaleY(float scaleY) translationX(float translationX) translationY(float translationY) CONSTRAINTS API…
  178. ConstraintLayout 2.0 preview visibility(int visibility) alpha(float alpha) elevation(float elevation) rotation(float

    rotation) rotationX(float rotationX) rotationY(float rotationY) scaleX(float scaleX) scaleY(float scaleY) translationX(float translationX) translationY(float translationY) translation(float translationX, float translationY) translationZ(float translationZ) constrainHeight(int height) constrainWidth(int width) constrainMaxHeight(int height) constrainMaxWidth(int width) constrainMinHeight(int height) constrainMinWidth(int width) constrainDefaultHeight(int height) constrainDefaultWidth(int width) horizontalWeight(float weight) verticalWeight(float weight) horizontalChainStyle(int chainStyle) verticalChainStyle(int chainStyle) addToHorizontalChain(int leftId, int rightId) addToHorizontalChainRTL(int leftId, int rightId) addToVerticalChain(int topId, int bottomId) removeFromVerticalChain() removeFromHorizontalChain() connect(int startSide, int endID, int endSide, int margin) CONSTRAINTS API…
  179. CONSTRAINT LAYOUT 2.0 - SUMMARY ➤ Virtual Layouts ➤ Layers

    & Transitions ➤ Decorators ➤ State management & Live Resize ➤ Fluent API for LayoutParams ➤ …more to come!
  180. THANKS! Nicolas Roard & John Hoford @camaelon @johnhoford

  181. CL 2.0 TO BE CONTINUED… … at Google IO 2018!

  182. DOCUMENTATION ➤ http://www.constraintlayout.com ➤ https://developer.android.com/reference/android/support/ constraint/package-summary.html ➤ https://developer.android.com/training/constraint-layout/ index.html ➤

    https://codelabs.developers.google.com/codelabs/constraint-layout ➤ https://medium.com/google-developers/building-interfaces-with- constraintlayout-3958fa38a9f7