The Tetris Model • Change is hard • Impose limits for animation / transitions • Not conductive to a great design tool experience • Performance can become an issue
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
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
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?…
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
What to Keep in Mind • match_constraint is more costly, as we need to remeasure • wrap_content, fixed dimension are cheaper • Fixed endpoints help to resolve directly, bypassing the solver • e.g match_constraint with no min/max, guidelines…
Tools attributes • tools: • tools:showIn • tools:layout • tools:listitem • tools:parentTag override attributes at design time shows this layout embedded in another one which layout to use for a fragment which layout for a list item define which layout to use as parent for merge tag https://developer.android.com/studio/write/tool-attributes.html
Sample Data • Baked-in data types • date, names, phone numbers… • JSON files • Resources in sample data folder • Text • Color • Image (collections if in folder)
Percent Dimension • width or height set to 0dp (“match_constraint”) • relative to the container • control behavior with: • app:layout_constraintWidth_percent=“0.20” • app:layout_constraintHeight_percent=“0.20”
Case 3 1. Horizontal chain between (1) and (2) 2. Chain is a packed chain 3. Horizontal bias is set to 0 4. (1) has app:layout_constrainedWidth=“true” 1 2
ConstraintSet • Separate views from the layout rules • Encapsulate all constraints of a layout in a single object • Let you apply a ConstraintSet to an existing ConstraintLayout
ConstraintSet • Separate views from the layout rules • Encapsulate all constraints of a layout in a single object • Let you apply a ConstraintSet to an existing ConstraintLayout • Let you switch between multiple ConstraintSet
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);
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);
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);
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);
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);