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

Chicago Roboto 2017: Cool ConstraintLayout

Chicago Roboto 2017: Cool ConstraintLayout

Huyen's talk on cool things about and cool things to do with ConstraintLayout given at Chicago Roboto 2017.

Huyen Tue Dao

April 21, 2017
Tweet

More Decks by Huyen Tue Dao

Other Decks in Programming

Transcript

  1. HUYEN TUE DAO
    @QUEENCODEMONKEY
    COOL
    CONSTRAINT
    LAYOUT
    SLIDES

    View Slide

  2. COOL THINGS ABOUT
    CONSTRAINT LAYOUT
    COOL THINGS TO DO
    WITH CONSTRAINT LAYOUT

    View Slide

  3. WHAT IS THE
    CONSTRAINT
    LAYOUT?

    View Slide

  4. RELATIONSHIPS BETWEEN VIEWS
    RELATIVE LAYOUT++
    + (≈LINEARLAYOUT)
    EXPRESSIVE
    PERFORMANT

    View Slide

  5. UNBUNDLED
    SUPPORTS API 9+
    UI BUILDER
    USABLE WITH XML ONLY

    View Slide

  6. HOW DOES IT
    WORK?

    View Slide

  7. CONSTRAINTS
    EQUATIONS
    SOLVER
    7
    HOW DOES IT WORK?

    View Slide

  8. HOW DOES IT WORK?
    CONSTRAINTS
    EQUATIONS
    SOLVER
    POSITION
    FIXED
    WRAP CONTENT
    MATCH CONSTRAINT
    RATIO
    EDGE
    CENTER
    BASELINE
    DIMENSION OTHER
    8
    GUIDELINES
    CHAINS
    CONSTRAINT SET

    View Slide

  9. CONSTRAINTS
    EQUATIONS
    SOLVER
    LINEAR SYSTEM OF EQUATIONS/INEQUALITIES
    9
    HOW DOES IT WORK?
    11 + … + 1n =
    11 + … + 1n ≤
    11 + … + 1n ≥

    View Slide

  10. CONSTRAINTS
    EQUATIONS
    SOLVER
    CASSOWARY
    LINEAR ARITHMETIC
    CONSTRAINT SOLVING
    ALGORITHM
    VIEW BOUNDS
    10
    HOW DOES IT WORK?

    View Slide

  11. CONSTRAINTLAYOUT, INSIDE AND OUT: PART 2 DAVE SMITH

    View Slide

  12. LET’S TAKE
    A QUICK
    TOUR

    View Slide

  13. View Slide

  14. CONSTRAINT
    LAYOUT
    CHEAT SHEET

    View Slide

  15. SOURCE
    TARGET
    EDGE CONSTRAINT

    app:layout_constraintLeft_toLeftOf="parent"

    app:layout_constraint_toOf=“a_view"

    View Slide

  16. CENTER CONSTRAINT

    app:layout_constraintHorizontal_bias="0.75"

    View Slide

  17. BASELINE CONSTRAINT
    app:layout_constraintBaseline_toBaselineOf="@+id/view"

    View Slide

  18. SIZE CONSTRAINTS

    View Slide

  19. GUIDELINES

    View Slide

  20. android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:id="@+id/guideline_start"

    android:orientation="vertical"

    app:layout_constraintGuide_begin="16dp" />



    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:id="@+id/horizontal"

    android:orientation="horizontal"

    app:layout_constraintGuide_percent="0.37" />

    View Slide

  21. SO WHAT CAN
    WE DO WITH
    CONSTRAINT
    LAYOUT?

    View Slide

  22. public class SquareImageView extends ImageView {
    @Override

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);


    final int size = Math.min(getMeasuredWidth(), getMeasuredHeight());

    setMeasuredDimension(size, size);

    }

    View Slide

  23. android:id=“@+id/square_image”

    android:layout_width="0dp"

    android:layout_height="0dp"

    app:layout_constraintDimensionRatio=“W,1:1"

    View Slide

  24. View Slide


  25. H,16:10

    app:layout_constraintDimensionRatio="@string/dimension_ratio_home_hero"

    View Slide

  26. IS IT REALLY
    BETTER THAN
    RELATIVE
    LAYOUT?

    View Slide

  27. STYLING ANDROID
    CONSTRAINTLAYOUT
    PART 6

    View Slide

  28. View Slide

  29. private fun updateManualAnchors() {

    val size = anchorMinSize + seekBar.progress

    val halfSize = Math.round(size * 0.5f)

    val horizontalMargin =
    resources.getDimensionPixelSize(R.dimen.content_margin_horizontal) - halfSize

    val verticalMargin =
    resources.getDimensionPixelSize(R.dimen.alignment_rectangle_margin_vertical) - halfSize

    updateManualAnchor(frameAnchorTop, size, verticalMargin, 0, 0, 0)

    updateManualAnchor(frameAnchorStart, size, 0, horizontalMargin, 0, 0)

    updateManualAnchor(frameAnchorBottom, size, 0, 0, verticalMargin, 0)

    updateManualAnchor(frameAnchorEnd, size, 0, 0, 0, horizontalMargin)

    }


    private fun updateManualAnchor(anchor: View, size: Int,

    marginTop: Int, marginStart: Int,

    marginBottom: Int, marginEnd: Int) {

    val layoutParams = anchor.layoutParams as FrameLayout.LayoutParams
    layoutParams.width = size

    layoutParams.height = size

    layoutParams.topMargin = marginTop

    layoutParams.bottomMargin = marginBottom

    layoutParams.marginStart = marginStart

    layoutParams.marginEnd = marginEnd
    anchor.layoutParams = layoutParams

    }
    WITH CONSTRAINTLAYOUT
    JUST CHANGE THE SIZE…

    View Slide

  30. WHAT WAS THAT
    ABOUT LINEAR
    LAYOUT?

    View Slide

  31. CHAINS. CHAINS. CHAINS.
    FROM CONSTRAINTLAYOUT DOCUMENTATION

    View Slide

  32. SPREAD INSIDE CHAIN
    android:id=“@+id/spread_inside_head”

    app:layout_constraintHorizontal_chainStyle="spread_inside"

    … />

    View Slide

  33. android:id=“@+id/weighted_chain_head

    android:layout_width="0dp"

    android:layout_height="wrap_content"

    app:layout_constraintHorizontal_chainStyle="spread"

    app:layout_constraintHorizontal_weight=“1" />
    android:id=“@+id/next
    android:layout_width="0dp"

    android:layout_height="wrap_content"

    app:layout_constraintHorizontal_weight="2" />
    android:id=“@+id/last

    android:layout_width="0dp"

    android:layout_height="wrap_content"

    app:layout_constraintHorizontal_weight="1" />
    33
    WEIGHTED CHAIN

    View Slide

  34. android:id=“@+id/packed_chain_head”

    app:layout_constraintHorizontal_chainStyle="packed"

    app:layout_constraintHorizontal_bias="0.12" />
    34
    PACKED CHAIN

    View Slide

  35. View Slide

  36. View Slide

  37. A CONSTRAINT
    LAYOUT SPECIAL
    CONSTRAINT SET

    View Slide

  38. CONSTRAINT SET
    CREATE/SAVE/APPLY
    CREATE MANUALLY
    CLONE A LAYOUT FILE
    CLONE A CONSTRAINT LAYOUT
    AWESOME WITH TRANSITIONS
    DEFINE SET OF CONSTRAINTS
    PROGRAMMATICALLY

    View Slide

  39. View Slide

  40. View Slide

  41. // Inflate initial layout as usual.
    setContentView(R.layout.activity_constraintset_01)
    // Get references to controls

    constraintLayout = findViewById(R.id.constraint_layout) as ConstraintLayout


    // Load ConstraintSets.

    constraintSet01.clone(constraintLayout)

    constraintSet02.clone(this, R.layout.activity_constraintset_02)
    …some time later…
    // Toggle ConstraintSets.
    TransitionManager.beginDelayedTransition(constraintLayout)

    if (original) constraintSet02.applyTo(constraintLayout)

    else constraintSet01.applyTo(constraintLayout)

    original = !original
    39

    View Slide

  42. YES, LIST ITEMS
    CAN BE
    CONSTRAINT
    LAYOUTS

    View Slide

  43. CONSTRAINT SET
    IN LIEU OF
    CUSTOM
    VIEWGROUP

    View Slide

  44. CUSTOM
    VIEW GROUPS
    GENERALIZED, REUSABLE LAYOUTS
    PERFORMANT COMPOSITE LAYOUTS
    LAYOUT IS LOW-LEVEL (X, Y)
    EVEN SIMPLE ONES = MUCH CODE
    ADVANCED LAYOUTS… WOAH

    View Slide

  45. @Override

    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

    MarginLayoutParams layoutParams = (MarginLayoutParams) icon.getLayoutParams();


    // Figure out the x-coordinate and y-coordinate of the icon.

    int x = getPaddingLeft() + layoutParams.leftMargin;

    int y = getPaddingTop() + layoutParams.topMargin;


    // Layout the icon.

    icon.layout(x, y, x + icon.getMeasuredWidth(), y + icon.getMeasuredHeight());


    // Calculate the x-coordinate of the title: icon's right coordinate +

    // the icon's right margin.

    x += icon.getMeasuredWidth() + layoutParams.rightMargin;


    // Add in the title's left margin.

    layoutParams = (MarginLayoutParams) titleView.getLayoutParams();

    x += layoutParams.leftMargin;


    // Calculate the y-coordinate of the title: this ViewGroup's top padding +

    // the title's top margin

    y = getPaddingTop() + layoutParams.topMargin;


    // Layout the title.

    titleView.layout(x, y, x + titleView.getMeasuredWidth(), y + titleView.getMeasuredHeight());


    // The subtitle has the same x-coordinate as the title. So no more calculating there.


    // Calculate the y-coordinate of the subtitle: the title's bottom coordinate +

    // the title's bottom margin.

    y += titleView.getMeasuredHeight() + layoutParams.bottomMargin;

    layoutParams = (MarginLayoutParams) subtitleView.getLayoutParams();


    // Add in the subtitle's top margin.

    y += layoutParams.topMargin;


    // Layout the subtitle.

    subtitleView.layout(x, y,

    x + subtitleView.getMeasuredWidth(), y + subtitleView.getMeasuredHeight());

    }

    View Slide

  46. CONSTRAINT
    SET IN LIEU OF
    CUSTOM
    VIEWGROUP

    View Slide

  47. private fun addRow(view: View) {

    constraintLayout.addView(view)


    val id = view.id

    constraintSet.constrainWidth(id, MATCH_CONSTRAINT)

    constraintSet.constrainHeight(id, rowHeight)


    // Constrain new view vertically.

    val target = if (lastRowId  PARENT_ID) TOP else BOTTOM

    constraintSet.connect(id, TOP, lastRowId, target)
    // Constrain new view horizontally.

    constraintSet.connect(id, START, PARENT_ID, START)

    constraintSet.connect(id, END, PARENT_ID, END)


    // Toggle elevation to elevate last added view.

    constraintSet.setElevation(id, resources.getDimension(R.dimen.elevation))

    constraintSet.setElevation(lastViewId, 0f)


    // Apply constraints.

    constraintSet.applyTo(constraintLayout)
    45

    View Slide

  48. private fun addRowItem(view: View) {

    …

    constraintLayout.addView(view)


    val id = view.id


    // Initialize width and height of new view.

    constraintSet.constrainWidth(id, MATCH_CONSTRAINT)

    constraintSet.constrainHeight(id, rowHeight)


    // Constrain new view vertically.

    val target = if (lastRowId  PARENT_ID) TOP else BOTTOM

    constraintSet.connect(id, TOP, lastRowId, target)
    46

    View Slide

  49. // Update current row.

    currentRowIds.add(id)

    // Re-create horizontal chain with other row items.

    constraintSet.createHorizontalChainRtl(

    PARENT_ID, START,

    PARENT_ID, END,

    currentRowIds.toIntArray(), FloatArray(currentRow.size, { 1f }),

    CHAIN_SPREAD_INSIDE)


    // Toggle elevation to elevate last added view.

    constraintSet.setElevation(id, resources.getDimension(R.dimen.elevation))

    constraintSet.setElevation(lastViewId, 0f)


    // Apply constraints.

    constraintSet.applyTo(constraintLayout)
    47

    View Slide

  50. SERIOUSLY
    COOL THINGS IN
    CONSTRAINT
    LAYOUT

    View Slide

  51. ANDROID DEVELOPERS BACKSTAGE
    EPISODE 50: CONSTRAINT LAYOUT

    View Slide

  52. CONSTRAINTLAYOUT CREW
    JOHN HOFORD
    @JOHNHOFORD
    NICOLAS ROARD
    @CAMAELON

    View Slide

  53. THANK YOU!
    SPEAKERDECK.COM/QUEENCODEMONKEY
    YOUTUBE.COM/ANDROIDDIALOGS
    RANDOMLYTYPING.COM
    HUYEN TUE DAO
    @QUEENCODEMONKEY
    QUEENCODEMONKEY/PRESENTATION-COOL-CONSTRAINTLAYOUT

    View Slide

  54. REFERENCES
    52
    CONSTRAINT LAYOUT APIS DOCUMENTATION
    https://developer.android.com/reference/android/support/constraint/package-summary.html
    BUILD A RESPONSIVE UI WITH CONSTRAINTLAYOUT
    developer.android.com/training/constraint-layout/index.html
    ANDROID DEVELOPERS BACKSTAGE: EPISODE 50: CONSTRAINT LAYOUT
    androidbackstage.blogspot.com/2016/06/episode-50-constraint-layout.html
    USING CONSTRAINTLAYOUT TO DESIGN YOUR VIEWS | CODE LABS
    codelabs.developers.google.com/codelabs/constraint-layout/index.html
    ANDROID LAYOUTS: A NEW WORLD | GOOGLE I/O 2016
    https://youtu.be/sO9aX87hq9c
    CONSTRAINTLAYOUT
    https://speakerdeck.com/writtmeyer/constraintlayout-1
    ADVANCED CONSTRAINTLAYOUT
    http://cfp.devoxx.us/2017/talk/XOD-8930/Advanced_ConstraintLayout

    View Slide

  55. REFERENCES
    53
    CONSTRAINTLAYOUT – PART 1
    blog.stylingandroid.com/constraintlayout-part-1/
    CONSTRAINTLAYOUT, INSIDE AND OUT: PART 1
    http://wiresareobsolete.com/2016/07/constraintlayout-part-1/
    SOME THOUGHTS ON ANDROID’S NEW CONSTRAINTLAYOUT AND ANDROID STUDIO’S NEW DESIGN EDITOR
    http://www.grokkingandroid.com/thoughts-on-constraintlayout-and-design-editor/
    BUILD A UI WITH LAYOUT EDITOR
    developer.android.com/studio/write/layout-editor.html
    WHAT'S NEW IN ANDROID DEVELOPMENT TOOLS | GOOGLE I/O 2016
    https://youtu.be/csaXml4xtN8
    THE EXPERTS' GUIDE TO ANDROID DEVELOPMENT TOOLS | GOOGLE I/O 2016
    https://youtu.be/hHnTIMjd1Y8
    JOHN HOFORD & NICOLAS ROARD : CONSTRAINTLAYOUT | ANDROID DIALOGS
    https://youtu.be/hHnTIMjd1Y8

    View Slide