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

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

Nicolas Roard

July 13, 2017
Tweet

More Decks by Nicolas Roard

Other Decks in Programming

Transcript

  1. ConstraintLayout
    Nicolas Roard

    View Slide

  2. What is it
    • Expressive Layout Manager
    • Flat Layouts
    • Deep integration with Android Studio + Layout Editor
    • Unbundled Library
    • Compatible with 99% of devices

    View Slide

  3. Once upon a time

    View Slide

























  4. View Slide

























  5. View Slide

  6. View Slide

  7. The Tetris Model

    View Slide

  8. The Tetris Model
    • Relatively easy at first

    View Slide

  9. The Tetris Model
    • Relatively easy at first
    • Can get very complex very quickly

    View Slide

  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

    View Slide

  11. View Slide

  12. View Slide

  13. View Slide

  14. View Slide

  15. View Slide

  16. Layout
    !=
    Views

    View Slide

  17. Flat Layouts

    View Slide

  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

    View Slide





































  19. View Slide

  20. $ANDROID_HOME/platform-tools/systrace/systrace.py
    —time=10 -o ~/trace.html gfx view res
    CL 1.0.2,
    Nexus 5X

    View Slide

  21. Expressivity

    View Slide

  22. Solver

    View Slide

  23. Simplex
    • Linear Programming
    • Invented by Georges Dantzig in 1947
    • Large, empty matrices representing the
    equations

    View Slide

  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

    View Slide

  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.

    View Slide

  26. Cassowary
    • Incremental resolution and construction of the system
    • Handles positive and negative variables
    • Goal function and error representation

    View Slide

  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?…

    View Slide

  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

    View Slide

  29. Constraints Model

    View Slide

  30. Constraints Model
    • Simple model — relative positioning, centering
    • No Equations exposed
    • Evolving (bias, new dimension constraints, etc.)

    View Slide

  31. Constraints Model

    View Slide

  32. Constraints Model

    View Slide

  33. Constraints Model

    View Slide

  34. Constraints Model

    View Slide

  35. Constraint Layout
    Solver
    Constraints Model

    View Slide

  36. Constraint Layout
    Solver
    Constraints Model
    Optimizer

    View Slide

  37. Optimizer

    View Slide

  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

    View Slide

  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)

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  43. Functionalities

    View Slide

  44. 1.0
    • Relative positioning
    • Center positioning & bias
    • Guidelines - helper objects
    • Chains
    • Dimension constraints: min/max, Ratio
    • ConstraintSet

    View Slide

  45. Gone Behavior

    View Slide

  46. Gone Behavior

    View Slide

  47. Inadapted Margin

    View Slide

  48. Inadapted Margin

    View Slide

  49. Gone Margins

    View Slide

  50. Gone Margins

    View Slide

  51. Example

    View Slide

  52. Example

    View Slide

  53. beta 1
    1.1.0

    View Slide

  54. • Barriers
    beta 1
    1.1.0

    View Slide

  55. • Barriers
    beta 1
    1.1.0

    View Slide

  56. • Barriers
    beta 1
    1.1.0

    View Slide

  57. Barriers

    View Slide

  58. Barriers

    View Slide

  59. Barriers

    View Slide

  60. Barriers

    View Slide

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

    View Slide

  62. • Barriers
    • Group - apply visibility to a set of widgets
    beta 1
    1.1.0

    View Slide

  63. Groups
    textview2
    textview3

    View Slide

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

    View Slide

  65. Groups
    Invisible Gone

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  69. • Barriers
    • Group
    • Placeholder
    • Percent dimensions
    beta 1
    1.1.0

    View Slide

  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

    View Slide

  71. View Slide

  72. default=wrap

    View Slide

  73. default=wrap

    View Slide

  74. default=wrap

    View Slide

  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"

    View Slide

  76. beta 1
    1.1.0
    maven {
    url "https://maven.google.com"
    }
    dependencies {
    ...
    compile 'com.android.support.constraint:constraint-layout:1.1.0-beta1'
    }

    View Slide

  77. ConstraintSet

    View Slide

  78. Layout
    !=
    Views

    View Slide

  79. ConstraintLayout Views

    View Slide

  80. ConstraintLayout Views
    ConstraintSet

    View Slide

  81. ConstraintLayout Views
    ConstraintSet

    View Slide

  82. ConstraintLayout Views
    ConstraintSet

    View Slide

  83. ConstraintSet

    View Slide

  84. ConstraintSet
    • Separate views from how we layout them

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  88. View Slide

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

    View Slide

  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);

    View Slide

  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);

    View Slide

  92. Landscape

    View Slide

  93. Rotation

    View Slide

  94. Rotation

    View Slide

  95. Motion

    View Slide

  96. Motion
    • Flat Hierarchy == No clipping issues

    View Slide

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

    View Slide

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

    View Slide

  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);

    View Slide

  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);

    View Slide

  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);

    View Slide

  102. View Slide

  103. View Slide

  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

    View Slide

  105. NavigationView

    View Slide

  106. NavigationView

    View Slide

  107. View Slide

  108. View Slide

  109. • |

    View Slide

  110. • |

    View Slide

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

    View Slide

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

    View Slide

  113. What’s next

    View Slide

  114. What’s next
    • More performance optimizations
    • experimental background resolution
    • segmentation of constraints
    • broadening the optimizer surface

    View Slide

  115. What’s next
    • ConstraintHelper
    • Chains
    • Layers
    • Custom
    • Motion
    • better motion control
    • gesture support

    View Slide

  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

    View Slide

  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

    View Slide

  118. Thank you!
    +NicolasRoard
    @camaelon
    http://b.android.com
    File bugs & requests on:

    View Slide