In Flutter, the layout principle of “Constraints go down, Sizes go up, Parent sets position” is a clear and distinct mechanism for handling the layout of widgets. When comparing this with the layout mechanisms in Android, iOS, and HTML5/CSS/JS, we find different approaches and philosophies. Let’s compare these systems to understand their similarities and differences.
Layout and Size in Different Systems
Flutter
- Constraints Go Down: Parent widgets send constraints to their children, specifying permissible sizes.
- Sizes Go Up: Children choose their size within those constraints.
- Parent Sets Position: Parents position children based on their size and constraints.
Android (View System)
- Measure Phase:
- Parent Determines Constraints: Parent views provide measurement specifications (
MeasureSpec) to children. - Children Measure Size: Children determine their desired size based on these specifications, including modes (
EXACTLY,AT_MOST,UNSPECIFIED).
- Parent Determines Constraints: Parent views provide measurement specifications (
- Layout Phase:
- Parent Sets Size and Position: Parents decide the final size and position of each child view using the
layout()method, setting exact bounds within the parent’s coordinate system.
- Parent Sets Size and Position: Parents decide the final size and position of each child view using the
iOS (UIKit)
- Constraints (Auto Layout):
- Constraints Propagation: Constraints define relationships between views, such as size ratios or alignments.
- Size Determination: Each view calculates its size based on these constraints and intrinsic content size.
- Layout Passes:
- Parent Resolves Constraints: Constraints are resolved to compute the frames (positions and sizes) of views.
- Frames Set Position: The final position and size of each view are determined by resolving the constraints to specific frames.
HTML5/CSS/JS
- CSS Box Model:
- Constraints Through CSS: CSS rules (like
width,height,max-width,min-width, etc.) define size constraints. - Size Computation: Elements calculate their size based on CSS rules, content size, and parent constraints.
- Constraints Through CSS: CSS rules (like
- Layout Mechanisms:
- Flow Layout: Default document flow where elements take up available space in order.
- Flexbox: Parent container defines constraints and alignment for flex items, which then size themselves within these constraints.
- Grid Layout: Parent defines a grid structure, and child elements size and position themselves within grid areas.
- Positioning:
- CSS Positioning: Elements can be positioned using properties like
position,top,left,right, andbottom, relative to their parent or document flow.
- CSS Positioning: Elements can be positioned using properties like
Comparison: Key Aspects
Constraints Handling
- Flutter: Constraints explicitly passed from parent to child in a hierarchical manner.
- Android: Constraints come from measure specs which include modes and sizes, less explicit than Flutter.
- iOS: Constraints are set using Auto Layout, forming a constraint system that is resolved for size and position.
- HTML/CSS: Constraints defined using CSS properties; more flexible and varied ways to specify constraints.
Size Determination
- Flutter: Children determine size within provided constraints.
- Android: Children measure themselves based on measure specs and report back desired sizes.
- iOS: Size determined by solving constraints in Auto Layout system.
- HTML/CSS: Size determined by CSS rules, intrinsic content, and parent constraints.
Positioning
- Flutter: Parent sets position of children after size determination.
- Android: Parent uses
layout()method to set position within bounds. - iOS: Position determined by resolving constraints to frames.
- HTML/CSS: Position determined by CSS properties and layout rules (flow, flexbox, grid).
Flexibility
- Flutter: Clear and flexible constraint-based system.
- Android: More rigid with fixed measure/layout phases.
- iOS: Flexible but complex due to constraint-solving.
- HTML/CSS: Highly flexible with multiple layout models (flow, flexbox, grid).
Examples
Flutter Example:
Container(
constraints: BoxConstraints(
minWidth: 100,
maxWidth: 200,
),
child: Text('Hello'),
)
- Constraints:
Containersends constraints toText. - Size:
Textchooses a size within constraints. - Position:
Containersets the position ofText.
Android Example:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello"/>
</LinearLayout>
- Constraints:
LinearLayoutprovides measure specs toTextView. - Size:
TextViewmeasures itself based on specs. - Position:
LinearLayoutsetsTextView’s position usinglayout().
iOS Example:
let container = UIView()
container.translatesAutoresizingMaskIntoConstraints = false
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "Hello"
container.addSubview(label)
NSLayoutConstraint.activate([
label.widthAnchor.constraint(greaterThanOrEqualToConstant: 100),
label.widthAnchor.constraint(lessThanOrEqualToConstant: 200),
label.centerXAnchor.constraint(equalTo: container.centerXAnchor),
label.centerYAnchor.constraint(equalTo: container.centerYAnchor)
])
- Constraints:
NSLayoutConstraintsets constraints onlabel. - Size:
UILabelsizes itself based on constraints. - Position: Constraints determine
UILabel’s position withincontainer.
HTML/CSS Example:
<div style="display: flex; justify-content: center; align-items: center; width: 200px; height: 200px;">
<div style="min-width: 100px; max-width: 200px;">
Hello
</div>
</div>
- Constraints: CSS properties define constraints.
- Size: Child
divsizes itself based on min and max width. - Position: Parent
divpositions the child using flexbox.
Summary
The layout systems in Flutter, Android, iOS, and HTML5/CSS/JS each have their own approaches:
