Share
Embed
ConstraintLayout 2.0 sneak peek
A presentation at ChicagoRoboto 2018 of what's coming up soon with ConstraintLayout 2.0
Nicolas Roard
April 12, 2018
Transcript
119 slides
-
ConstraintLayout 2.0 preview CONSTRAINT LAYOUT 1.1 ➤ Constraints ➤ Helper
objects ➤ Optimizer ➤ ton of bug fixes! -
ConstraintLayout 2.0 preview CONSTRAINTS ➤ Constrained Dimensions : percent, min/max,
wrap ➤ Circular constraints ➤ Complex chains -
ConstraintLayout 2.0 preview CIRCULAR CONSTRAINTS <Button android:id="@+id/buttonA" ... /> <Button
android:id="@+id/buttonB" … app:layout_constraintCircle=“@+id/buttonA" app:layout_constraintCircleRadius=“100dp" app:layout_constraintCircleAngle="45" /> -
ConstraintLayout 2.0 preview 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 -
ConstraintLayout 2.0 preview GROUPS ➤ Define a set of widgets
➤ Apply visibility to them Helper object -
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 -
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 -
ConstraintLayout 2.0 preview OPTIMIZER ➤ New optimizer in 1.1 ➤
A lot more powerful :) ➤ Multiple optimizations passes available ➤ Direct & Center connections ➤ Barriers ➤ Chains (experimental) ➤ Dimensions (experimental) -
ConstraintLayout 2.0 preview TOOLING ➤ Integrated manipulation in the component
tree (like for barriers) ➤ Exposed in the Palette ➤ Support 3rd party libraries ➤ exposing their custom views / helpers -
ConstraintLayout 2.0 preview THREE MAIN CATEGORIES OF HELPERS Layout Manipulation
Rendering or Decorating Post-Layout Manipulation -
ConstraintLayout 2.0 preview 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 -
ConstraintLayout 2.0 preview API ➤ Access a list of views
➤ pre/post layouts callbacks ➤ normal views ➤ already used ➤ barriers ➤ groups -
ConstraintLayout 2.0 preview COLLECTION ➤ Trampoline object ➤ forward function
calls to referenced views ➤ setVisibility ➤ setAlpha ➤ setRotation, etc. ➤ no getter! -
ConstraintLayout 2.0 preview DECORATORS ➤ Can reference views ➤ Easily
build decorators that depends on views location / visibility / etc -
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 } } -
ConstraintLayout 2.0 preview LAYER DECORATOR ➤ Group ++ ➤ Manipulate
graphically a collection of views ➤ Supports transforms, etc. ➤ Can be set as the bounding box of the referenced views -
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 -
ConstraintLayout 2.0 preview LAYER DECORATOR <android.support.constraint.Layer android:id=“@+id/layer” android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/frame"
android:padding="32dp" app:constraint_referenced_ids=“button1,button2,button3, button4,button5” /> -
ConstraintLayout 2.0 preview LAYER DECORATOR <android.support.constraint.Layer android:id=“@+id/layer” android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/frame"
android:padding="32dp" app:constraint_referenced_ids=“button1,button2,button3, button4,button5” /> -
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); -
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); } } -
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(); } -
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" /> -
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; } } -
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; } -
ConstraintLayout 2.0 preview DECORATOR HELPERS ➤ Tag your views with
behavior ➤ Encapsulate behavior ➤ Declaratively use them -
ConstraintLayout 2.0 preview VIRTUAL LAYOUTS ➤ Layout the referenced views
➤ Still keep flat hierarchy ➤ Linear ➤ Flow -
ConstraintLayout 2.0 preview LINEAR ➤ Create horizontal or vertical chains
➤ Somewhat similar to linear layout, but as a helper -
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" /> -
ConstraintLayout 2.0 preview <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="20dp" android:layout_marginTop="20dp" android:text="TextView"
app:layout_constraintStart_toEndOf="@+id/linear" app:layout_constraintTop_toBottomOf="@+id/linear" /> -
ConstraintLayout 2.0 preview 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 -
ConstraintLayout 2.0 preview FLOW <android.support.constraint.Flow android:id="@+id/flow" app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="8dp" app:constraint_referenced_ids=“button1,button2,button3,button4, button5,button6,button7,button8"
android:layout_width="match_parent" android:layout_height="wrap_content"/> -
ConstraintLayout 2.0 preview REFERENCE BUTTONS <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"/> -
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> -
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); } -
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; } -
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> -
ConstraintLayout 2.0 preview ON CONFIGURATION CHANGE @Override public void onConfigurationChanged(Configuration
newConfig) { super.onConfigurationChanged(newConfig); cl.setState(newConfig.screenWidthDp, newConfig.screenHeightDp); } -
ConstraintLayout 2.0 preview CALLBACK cl.setOnConstraintsChanged(new ConstraintsChangedListener() { @Override public void
preLayoutChange(int state,int layoutId) { TransitionManager.beginDelayedTransition(cl); } }); -
ConstraintLayout 2.0 preview 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 -
ConstraintLayout 2.0 preview 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 -
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(); -
ConstraintLayout 2.0 preview EXAMPLE : CENTER Constraints.on(myView) .center(R.id.button1, LEFT, R.id.button2,
RIGHT) .horizontalBias(.5f) .top(PARENT_ID,TOP,32) .apply(); -
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) CONSTRAINTS API… 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 -
ConstraintLayout 2.0 preview CONSTRAINT LAYOUT 2.0 - SUMMARY ➤ Virtual
Layouts ➤ Layers & Transitions ➤ Decorators ➤ State management & Live Resize ➤ Fluent API for LayoutParams ➤ …more to come! -
ConstraintLayout 2.0 preview 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