Advanced ConstraintLayout

Advanced ConstraintLayout

ConstraintLayout 1.0 made building flexible UI easy, with a deep integration in the Android Studio layout editor. The recently introduced 1.1 version is bringing even more flexibility, with new capabilities like barriers or groups. This talk will take a deeper look at the current state of the library, why you should use it and when: architecture, performance behavior, examples of complex UI, animation capabilities and discussing some upcoming features.

presented at 360 AnDev 2017

B9012970f22b84c5b344ffa6f8a884d5?s=128

Nicolas Roard

July 13, 2017
Tweet

Transcript

  1. ConstraintLayout Nicolas Roard

  2. What is it • Expressive Layout Manager • Flat Layouts

    • Deep integration with Android Studio + Layout Editor • Unbundled Library • Compatible with 99% of devices
  3. Once upon a time

  4. <RelativeLayout > <ImageView /> <ImageView /> <RelativeLayout > <TextView />

    <LinearLayout > <TextView /> <RelativeLayout > <EditText /> </RelativeLayout> </LinearLayout> <LinearLayout > <TextView /> <RelativeLayout > <EditText /> </RelativeLayout> </LinearLayout> <TextView /> </RelativeLayout> <LinearLayout > <Button /> <Button /> </LinearLayout> </RelativeLayout>
  5. <RelativeLayout > <ImageView /> <ImageView /> <RelativeLayout > <TextView />

    <LinearLayout > <TextView /> <RelativeLayout > <EditText /> </RelativeLayout> </LinearLayout> <LinearLayout > <TextView /> <RelativeLayout > <EditText /> </RelativeLayout> </LinearLayout> <TextView /> </RelativeLayout> <LinearLayout > <Button /> <Button /> </LinearLayout> </RelativeLayout>
  6. None
  7. The Tetris Model

  8. The Tetris Model • Relatively easy at first

  9. The Tetris Model • Relatively easy at first • Can

    get very complex very quickly
  10. The Tetris Model • Change is hard • Impose limits

    for animation / transitions • Not conductive to a great design tool experience • Performance can become an issue
  11. None
  12. None
  13. None
  14. None
  15. None
  16. Layout != Views

  17. Flat Layouts

  18. Flat Layouts • Layout definition is not mixed with the

    view hierarchy • Easy to manipulate in a graphical editor • Easy to change • Animation friendly • Keep layout computation in a single place
  19. <RelativeLayout > <ImageView /> <ImageView /> <RelativeLayout > <TextView />

    <LinearLayout > <TextView /> <RelativeLayout > <EditText /> </RelativeLayout> </LinearLayout> <LinearLayout > <TextView /> <RelativeLayout > <EditText /> </RelativeLayout> </LinearLayout> <TextView /> </RelativeLayout> <LinearLayout > <Button /> <Button /> </LinearLayout> </RelativeLayout> <android.support.constraint.ConstraintLayout> <ImageView /> <ImageView /> <TextView /> <EditText /> <TextView /> <TextView /> <EditText /> <Button /> <Button /> <TextView /> </android.support.constraint.ConstraintLayout>
  20. $ANDROID_HOME/platform-tools/systrace/systrace.py —time=10 -o ~/trace.html gfx view res CL 1.0.2, Nexus

    5X
  21. Expressivity

  22. Solver

  23. Simplex • Linear Programming • Invented by Georges Dantzig in

    1947 • Large, empty matrices representing the equations
  24. Example Minimize Constrained by Z x y z s t

    = Basic Feasible Solution (BFS) Matrix representation (plus slack variables s & t) Pivot on z, row 2 BFS Objective row
  25. Cassowary • https://constraints.cs.washington.edu/cassowary/ • Constraints for User Interface Applications •

    Alan Borning, Kim Marriott, Peter Stuckey, and Yi Xiao, Solving Linear Arithmetic, Proceedings of the 1997 ACM Symposium on User Interface Software and Technology, October 1997, pages 87-96.
  26. Cassowary • Incremental resolution and construction of the system •

    Handles positive and negative variables • Goal function and error representation
  27. Pros / Cons • Very flexible, can represent any type

    of layout situation • But “relatively” heavy computation compared to simple layouts • Can be more memory intensive • Specifying layout via equations?…
  28. ConstraintLayout solver • Pure java • Represents the system matrix

    as rows of sparse arrays • Memory Efficient • Efficient incremental construction • Has to have good performances on both Dalvik and Art
  29. Constraints Model

  30. Constraints Model • Simple model — relative positioning, centering •

    No Equations exposed • Evolving (bias, new dimension constraints, etc.)
  31. Constraints Model

  32. Constraints Model

  33. Constraints Model

  34. Constraints Model

  35. Constraint Layout Solver Constraints Model

  36. Constraint Layout Solver Constraints Model Optimizer

  37. Optimizer

  38. Optimizer • Constraints which can be resolved unambiguously • app:layout_optimizationLevel=“none|all|basic|chains”

    • multiple steps: • wrap content computation • direct resolution of simple dependency • chains on parent
  39. Optimizer • match_constraint is more costly, as we need to

    remeasure • wrap_content, fixed dimension are cheap on a widget (end up as a value in the solver)
  40. Optimizer - wrap content • If widgets contain match_constraint, no

    optimizations: • if ratio is specified • if percent is specified (for dimension, guideline) • if wrap_content is specified in the other dimension
  41. Optimizer - Direct resolution • Only if the container is

    not in wrap_content • Only for widgets that are not match_constraints • Will resolve as much as it can before handing the system to the full solver
  42. Optimizer - Chains • Only for chains that are connected

    to the container (stable endpoints) • Only for widgets in a chain that are not match_constraints / ratio • Right now, only for chains in spread mode
  43. Functionalities

  44. 1.0 • Relative positioning • Center positioning & bias •

    Guidelines - helper objects • Chains • Dimension constraints: min/max, Ratio • ConstraintSet
  45. Gone Behavior

  46. Gone Behavior

  47. Inadapted Margin

  48. Inadapted Margin

  49. Gone Margins

  50. Gone Margins

  51. Example

  52. Example

  53. beta 1 1.1.0

  54. • Barriers beta 1 1.1.0

  55. • Barriers beta 1 1.1.0

  56. • Barriers beta 1 1.1.0

  57. Barriers

  58. Barriers

  59. Barriers

  60. Barriers

  61. Barriers <android.support.constraint.Barrier android:id="@+id/barrier" android:layout_width="wrap_content" android:layout_height="wrap_content" app:barrierDirection="right" app:constraint_referenced_ids="textView1,textView2,textView3" />

  62. • Barriers • Group - apply visibility to a set

    of widgets beta 1 1.1.0
  63. Groups textview2 textview3

  64. Groups <android.support.constraint.Group android:id="@+id/group2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="visible" app:constraint_referenced_ids="textView2,textView3" />

  65. Groups Invisible Gone

  66. • Barriers • Group • Placeholder beta 1 1.1.0 ?

  67. class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } fun select(v: View) { TransitionManager.beginDelayedTransition(main_layout) placeholder.setContentId(v.id) main_title.text= v.tag as CharSequence?;""; } } Placeholder
  68. class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } fun select(v: View) { TransitionManager.beginDelayedTransition(main_layout) placeholder.setContentId(v.id) main_title.text= v.tag as CharSequence?;""; } } Placeholder
  69. • Barriers • Group • Placeholder • Percent dimensions beta

    1 1.1.0
  70. Dimension Constraints • width|height set to 0dp (“match_constraint”) • control

    behavior with • app:layout_constraintWidth_default=“spread|wrap|percent” • spread matches endpoints • wrap behave like wrap_content, but respect constraints
  71. None
  72. default=wrap

  73. default=wrap

  74. default=wrap

  75. Percent Dimension • As a percentage of the parent container

    • Not bounded by the container • value from 0 to 1 android:layout_width="0dp" app:layout_constraintWidth_default="percent" app:layout_constraintWidth_percent="0.5"
  76. beta 1 1.1.0 maven { url "https://maven.google.com" } dependencies {

    ... compile 'com.android.support.constraint:constraint-layout:1.1.0-beta1' }
  77. ConstraintSet

  78. Layout != Views

  79. ConstraintLayout Views

  80. ConstraintLayout Views ConstraintSet

  81. ConstraintLayout Views ConstraintSet

  82. ConstraintLayout Views ConstraintSet

  83. ConstraintSet

  84. ConstraintSet • Separate views from how we layout them

  85. ConstraintSet • Separate views from how we layout them •

    Encapsulate all constraints in an object
  86. ConstraintSet • Separate views from how we layout them •

    Encapsulate all constraints in an object • You can apply a ConstraintSet to an existing ConstraintLayout
  87. ConstraintSet • Separate views from how we layout them •

    Encapsulate all constraints in an object • You can apply a ConstraintSet to an existing ConstraintLayout • Switch between multiple ConstraintSet
  88. None
  89. ConstraintSet mConstraintSet1 = new ConstraintSet(); ConstraintSet mConstraintSet2 = new ConstraintSet();

  90. ConstraintSet mConstraintSet1 = new ConstraintSet(); ConstraintSet mConstraintSet2 = new ConstraintSet();

    // get constraints from layout mConstraintSet2.clone(context, R.layout.state2); setContentView(R.layout.state1); mConstraintLayout = (ConstraintLayout) findViewById(R.id.activity_main); // get constraints from ConstraintSet mConstraintSet1.clone(mConstraintLayout);
  91. ConstraintSet mConstraintSet1 = new ConstraintSet(); ConstraintSet mConstraintSet2 = new ConstraintSet();

    // get constraints from layout mConstraintSet2.clone(context, R.layout.state2); setContentView(R.layout.state1); mConstraintLayout = (ConstraintLayout) findViewById(R.id.activity_main); // get constraints from ConstraintSet mConstraintSet1.clone(mConstraintLayout); mConstraintSet1.applyTo(mConstraintLayout);
  92. Landscape

  93. Rotation

  94. Rotation

  95. Motion

  96. Motion • Flat Hierarchy == No clipping issues

  97. Motion • Flat Hierarchy == No clipping issues • Scene

    Graph
  98. Motion • Flat Hierarchy == No clipping issues • Scene

    Graph • ConstraintSet == Keyframe
  99. ConstraintSet mConstraintSet1 = new ConstraintSet(); ConstraintSet mConstraintSet2 = new ConstraintSet();

    // get constraints from layout mConstraintSet2.clone(context, R.layout.state2); setContentView(R.layout.state1); mConstraintLayout = (ConstraintLayout) findViewById(R.id.activity_main); // get constraints from ConstraintSet mConstraintSet1.clone(mConstraintLayout); mConstraintSet1.applyTo(mConstraintLayout);
  100. ConstraintSet mConstraintSet1 = new ConstraintSet(); ConstraintSet mConstraintSet2 = new ConstraintSet();

    // get constraints from layout mConstraintSet2.clone(context, R.layout.state2); setContentView(R.layout.state1); mConstraintLayout = (ConstraintLayout) findViewById(R.id.activity_main); // get constraints from ConstraintSet mConstraintSet1.clone(mConstraintLayout); mConstraintSet1.applyTo(mConstraintLayout);
  101. TransitionManager.beginDelayedTransition(mConstraintLayout); ConstraintSet mConstraintSet1 = new ConstraintSet(); ConstraintSet mConstraintSet2 = new

    ConstraintSet(); // get constraints from layout mConstraintSet2.clone(context, R.layout.state2); setContentView(R.layout.state1); mConstraintLayout = (ConstraintLayout) findViewById(R.id.activity_main); // get constraints from ConstraintSet mConstraintSet1.clone(mConstraintLayout); mConstraintSet1.applyTo(mConstraintLayout);
  102. None
  103. None
  104. ConstraintLayout : choreographer • What you can do with widgets,

    you can do with components • Everything is still the same • Flexible • Easy to build and test
  105. NavigationView

  106. NavigationView

  107. None
  108. None
  109. • |

  110. • |

  111. Custom Transitions • ConstraintSet • Custom TransitionSet • Support library

    physics TransitionManager.beginDelayedTransition(cl, new MyCustomAnimationSet())
  112. Custom Transitions • ConstraintSet • Custom TransitionSet • Support library

    physics TransitionManager.beginDelayedTransition(cl, new MyCustomAnimationSet())
  113. What’s next

  114. What’s next • More performance optimizations • experimental background resolution

    • segmentation of constraints • broadening the optimizer surface
  115. What’s next • ConstraintHelper • Chains • Layers • Custom

    • Motion • better motion control • gesture support
  116. 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
  117. 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
  118. Thank you! +NicolasRoard @camaelon http://b.android.com File bugs & requests on: