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.

Nicolas Roard

April 23, 2018
Tweet

More Decks by Nicolas Roard

Other Decks in Programming

Transcript

  1. 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
  2. OPTIMIZER ➤ New optimizer in 1.1 ➤ A lot more

    powerful :) ➤ Multiple optimizations passes available ➤ Direct & Center connections ➤ Barriers ➤ Chains (experimental) ➤ Dimensions (experimental)
  3. CHAINS OPTIMIZER ➤ Apply if all elements have fixed dimensions

    ➤ Or if all elements are (simple) match_constraint ➤ …more to come
  4. WHAT’S A HELPER ➤ Not necessarily part of your view

    hierarchy ➤ Helps you specify and build your UI ➤ example: Guideline, Barrier
  5. 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
  6. API ➤ Access a list of views ➤ pre/post layouts

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

    barriers) ➤ Exposed in the Palette ➤ Support 3rd party libraries ➤ exposing their custom views / helpers
  8. EXAMPLE : COLLECTION HELPER ➤ Trampoline object ➤ forward function

    calls to referenced views ➤ setVisibility ➤ setAlpha ➤ setRotation, etc. ➤ no getter!
  9. DECORATORS ➤ Can reference views ➤ Easily build decorators that

    depends on views location / visibility / etc
  10. 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 } }
  11. LAYER DECORATOR ➤ Manipulate graphically a collection of views ➤

    Supports transforms, etc. ➤ Can be set as the bounding box of the referenced views
  12. 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
  13. 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);
  14. 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);
  15. 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" />
  16. 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); } }
  17. 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(); }
  18. 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; } }
  19. 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; }
  20. SUMMARY : HELPERS ➤ Tag your views with behavior ➤

    Encapsulate behavior ➤ Declaratively use them ➤ Tool integration
  21. 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" />
  22. 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
  23. 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"/>
  24. 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>
  25. 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); }
  26. 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; }
  27. 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>
  28. ConstraintLayout 2.0 preview ON CONFIGURATION CHANGE @Override public void onConfigurationChanged(Configuration

    newConfig) { super.onConfigurationChanged(newConfig); cl.setState(newConfig.screenWidthDp, newConfig.screenHeightDp); }
  29. ConstraintLayout 2.0 preview CALLBACK cl.setOnConstraintsChanged(new ConstraintsChangedListener() { @Override public void

    preLayoutChange(int state,int layoutId) { TransitionManager.beginDelayedTransition(cl); } });
  30. 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
  31. 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
  32. 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();
  33. 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…
  34. 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…
  35. CONSTRAINT LAYOUT 2.0 - SUMMARY ➤ Virtual Layouts ➤ Layers

    & Transitions ➤ Decorators ➤ State management & Live Resize ➤ Fluent API for LayoutParams ➤ …more to come!
  36. 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