Friday, April 26, 2019

ConstraintLayout 2.0.0 alpha 5

We just released ConstraintLayout 2.0.0 alpha 5. It’s available from the google maven repository:


dependencies {
  implementation 'com.android.support.constraint:constraint-layout:2.0.0-alpha5'
}


or if using the AndroidX packages:


dependencies {
   implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha5'
}


Documentation is available on https://developer.android.com/reference/android/support/constraint/classes.html

Examples are available on https://github.com/googlesamples/android-ConstraintLayoutExamples

Changes



This release contains various bug fixes and performance improvements:


ConstraintLayout
  • New: Flow virtual layout
MotionLayout

  • Various fixes (layout updates)
  • Auto transition (autoTransition)
  • Derived Constraints (deriveConstraintsFrom)
  • OnSwipe regions (touchRegionId)
  • MotionTarget matching (layout_constraintTag, motionTarget)
  • OnSwipe without automatically completing (autoComplete=”false”)
  • If OnClick has no target id the MotionLayout is targeted

Flow Virtual layout


Flow is a virtual layout. It can be used within a ConstraintLayout and supports multiple ways of laying out the referenced widgets (create a single chain, or multiple chains to wrap around, or a table). The advantages of being a virtual layout compared to a normal viewgroups are that:

  • The layout hierarchy remains flat, simplifying runtime manipulations and animations
  • You can constrain the Flow widget as you would any other view.
  • You can constrain other views to views laid out by Flow.
  • Within MotionLayout you can animate views into and out of a flow virtual layout, change its orientation, etc.

Flow will lay out widgets either horizontally or vertically, depending on the value of the android:orientation attribute. The next important attribute to set is flow_wrapMode, which will control how the referenced widgets are laid out in the given orientation:

  • app:flow_wrapMode = “none” will create a single chain out of the referenced elements (default)
  • app:flow_wrapMode = “chain” will create multiple chains (one after the other) if the referenced elements do not fit in the available space
  • app:flow_wrapMode = “aligned” is a bit similar to wrap chain, but will align the elements, basically creating rows and columns

The way elements are positioned for the other orientation is controlled by flow_horizontalAlign and flow_verticalAlign attributes. For example, if specifying a horizontal orientation, use flow_verticalAlign to control the vertical positioning of the elements being laid out.
  • android:orientation = “horizontal|vertical” (default horizontal)
  • app:flow_horizontalStyle = "spread|spread_inside|packed" (default spread)
  • app:flow_verticalStyle = "spread|spread_inside|packed" (default spread)
  • app:flow_horizontalBias = "float" (default 0.5)
  • app:flow_verticalBias = "float" (default 0.5)
  • app:flow_horizontalGap = "dimension" (default 0)
  • app:flow_verticalGap = "dimension" (default 0)
  • app:flow_horizontalAlign = "start|end|center" (default center)
  • app:flow_verticalAlign = "top|bottom|center|baseline” (default center)
  • app:flow_maxElementsWrap = "integer" (default : 0, not applied)

New features of MotionLayout

We also added several new features to MotionLayout.

Auto Transition


Transitions can be made to automatically fire when MotionLayout reaches a state associated with that transition.
  • none - default value no transitions automatically
  • animateToStart - animate to the start state if you are at the end state
  • animateToEnd - animate to the end state if you are at the start state
  • jumpToEnd - Jump to the start state if you are at the start state
  • jumpToStart - Jump to the end state if you are at the end state

These can be combined to allow jumping to the end but smooth transition to the start.

<Transition
  motion:constraintSetStart="@+id/end"
  motion:constraintSetEnd="@+id/b"
  motion:autoTransition="animateToEnd"
  motion:motionInterpolator="easeIn"
  motion:duration="1000"/>


Derived Constraints


Constraint sets can now be derived from other constraints sets. This can greatly reduce xml size. In a <ConstraintSet> can now have an attribute deriveConstraintsFrom which allows you to specify the id of another constraint set. This is useful for generating a series of constraints that only have small variations between them.

Note:
  • A constraint set represents the complete set of constraints for a layout
  • This works well in conjunction with the newer PropertySet, Layout, Transform syntax
  • All ConstraintSets derive from from the MotionLayout by default


<!-- Content of layout file  -->
<ConstraintSet android:id="@+id/base">
</ConstraintSet>

<!-- Layout file but override visibility of region1 (region1 now gone ) -->
<ConstraintSet android:id="@+id/state1">
  <Constraint
      android:id="@id/region1">
      <PropertySet
          motion:visibility="gone"/>
  </Constraint>
</ConstraintSet>

<!-- State1 (above) but override visibility of region2 (both region1 & region2 gone) -->
<ConstraintSet android:id="@+id/state2"
  motion:deriveConstraintsFrom="@id/state1">
  <Constraint
      android:id="@id/region2">
      <PropertySet
          motion:visibility="gone"/>
  </Constraint>
</ConstraintSet>

OnSwipe regions


OnSwipe now takes an attribute touchRegionId which limits the starting point of the bounds of that view.

Note:
  • The view pointed to by the id can be invisible
  • Quite often the region is the same as the anchor.
  • This allows two Transition swipes to be in effect in the same direction normally each transition is in a different direction.


<OnSwipe
  motion:dragDirection="dragDown"
  motion:touchAnchorId="@+id/region2"
  motion:touchRegionId="@+id/region2"
  motion:touchAnchorSide="top" />

Swipe without autocomplete


OnSwipe Automatically completes the transition choosing the direction and animating smoothly to a stop. Sometimes this feature is not desired and can be turned off.

You can use this to implement things like a custom slider.
<OnSwipe
  motion:dragDirection="dragRight"
  motion:autoComplete="false"
  motion:touchAnchorId="@+id/button"
  motion:touchAnchorSide="right" />