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 full-size 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 full-size slide

  3. Once upon a time

    View full-size slide

  4. The Tetris Model

    View full-size slide

  5. The Tetris Model
    • Relatively easy at first

    View full-size slide

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

    View full-size slide

  7. 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 full-size slide

  8. Layout
    !=
    Views

    View full-size slide

  9. Flat Layouts

    View full-size slide

  10. 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 full-size slide

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

    View full-size slide

  12. Expressivity

    View full-size slide

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

    View full-size slide

  14. 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 full-size slide

  15. 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 full-size slide

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

    View full-size slide

  17. 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 full-size slide

  18. 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 full-size slide

  19. Constraints Model

    View full-size slide

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

    View full-size slide

  21. Constraints Model

    View full-size slide

  22. Constraints Model

    View full-size slide

  23. Constraints Model

    View full-size slide

  24. Constraints Model

    View full-size slide

  25. Constraint Layout
    Solver
    Constraints Model

    View full-size slide

  26. Constraint Layout
    Solver
    Constraints Model
    Optimizer

    View full-size slide

  27. 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 full-size slide

  28. 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 full-size slide

  29. 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 full-size slide

  30. 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 full-size slide

  31. 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 full-size slide

  32. Functionalities

    View full-size slide

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

    View full-size slide

  34. Gone Behavior

    View full-size slide

  35. Gone Behavior

    View full-size slide

  36. Inadapted Margin

    View full-size slide

  37. Inadapted Margin

    View full-size slide

  38. Gone Margins

    View full-size slide

  39. Gone Margins

    View full-size slide

  40. • Barriers
    beta 1
    1.1.0

    View full-size slide

  41. • Barriers
    beta 1
    1.1.0

    View full-size slide

  42. • Barriers
    beta 1
    1.1.0

    View full-size slide

  43. 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 full-size slide

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

    View full-size slide

  45. Groups
    textview2
    textview3

    View full-size slide

  46. 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 full-size slide

  47. Groups
    Invisible Gone

    View full-size slide

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

    View full-size slide

  49. 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 full-size slide

  50. 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 full-size slide

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

    View full-size slide

  52. 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 full-size slide

  53. default=wrap

    View full-size slide

  54. default=wrap

    View full-size slide

  55. default=wrap

    View full-size slide

  56. 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 full-size slide

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

    View full-size slide

  58. ConstraintSet

    View full-size slide

  59. Layout
    !=
    Views

    View full-size slide

  60. ConstraintLayout Views

    View full-size slide

  61. ConstraintLayout Views
    ConstraintSet

    View full-size slide

  62. ConstraintLayout Views
    ConstraintSet

    View full-size slide

  63. ConstraintLayout Views
    ConstraintSet

    View full-size slide

  64. ConstraintSet

    View full-size slide

  65. ConstraintSet
    • Separate views from how we layout them

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  68. 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 full-size slide

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

    View full-size slide

  70. 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 full-size slide

  71. 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 full-size slide

  72. Motion
    • Flat Hierarchy == No clipping issues

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  75. 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 full-size slide

  76. 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 full-size slide

  77. 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 full-size slide

  78. 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 full-size slide

  79. NavigationView

    View full-size slide

  80. NavigationView

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  83. What’s next

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  86. 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 full-size slide

  87. 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 full-size slide

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

    View full-size slide