Layout widgets control how child widgets are positioned and sized.
Arrange widgets vertically (Column) or horizontally (Row).
&widgets.Column{
Children: []goflow.Widget{
&widgets.Text{Data: "First"},
&widgets.Text{Data: "Second"},
&widgets.Text{Data: "Third"},
},
MainAxisAlign: widgets.MainAxisCenter,
CrossAxisAlign: widgets.CrossAxisCenter,
}&widgets.Row{
Children: []goflow.Widget{
&widgets.Text{Data: "Left"},
&widgets.Text{Data: "Center"},
&widgets.Text{Data: "Right"},
},
MainAxisAlignment: widgets.MainAxisSpaceBetween,
CrossAxisAlignment: widgets.CrossAxisCenter,
}MainAxisAlignment (vertical for Column, horizontal for Row):
MainAxisStart- Start of axisMainAxisEnd- End of axisMainAxisCenter- Center of axisMainAxisSpaceBetween- Space evenly between childrenMainAxisSpaceAround- Space around childrenMainAxisSpaceEvenly- Space evenly including edges
CrossAxisAlignment (horizontal for Column, vertical for Row):
CrossAxisStart- Start of cross axisCrossAxisEnd- End of cross axisCrossAxisCenter- Center of cross axisCrossAxisStretch- Stretch to fill
&widgets.Row{
Children: []goflow.Widget{
&widgets.Expanded{
Flex: 2,
Child: &widgets.Container{
Color: goflow.NewColor(255, 200, 200, 255),
Child: &widgets.Text{Data: "2/3 width"},
},
},
&widgets.Expanded{
Flex: 1,
Child: &widgets.Container{
Color: goflow.NewColor(200, 255, 200, 255),
Child: &widgets.Text{Data: "1/3 width"},
},
},
},
}Layer widgets on top of each other.
&widgets.Stack{
Children: []goflow.Widget{
// Background
&widgets.Container{
Width: floatPtr(200),
Height: floatPtr(200),
Color: goflow.NewColor(200, 200, 255, 255),
},
// Foreground (centered)
&widgets.Align{
Alignment: widgets.AlignmentCenter,
Child: &widgets.Text{Data: "Centered"},
},
// Top-right corner
&widgets.Align{
Alignment: widgets.AlignmentTopRight,
Child: widgets.NewIcon(widgets.IconClose),
},
},
Fit: widgets.StackFitExpand,
}Alignment: Where non-positioned children are placed
StackAlignmentTopLeftStackAlignmentTopCenterStackAlignmentTopRightStackAlignmentCenterLeftStackAlignmentCenterStackAlignmentCenterRightStackAlignmentBottomLeftStackAlignmentBottomCenterStackAlignmentBottomRight
Fit: How non-positioned children are sized
StackFitLoose- Natural sizeStackFitExpand- Fill the stackStackFitPassthrough- Pass parent constraints
Position a child within a Stack precisely.
&widgets.Stack{
Children: []goflow.Widget{
background,
&widgets.Positioned{
Left: floatPtr(10),
Top: floatPtr(20),
Child: &widgets.Text{Data: "10px from left, 20px from top"},
},
&widgets.Positioned{
Right: floatPtr(10),
Bottom: floatPtr(10),
Width: floatPtr(100),
Height: floatPtr(50),
Child: badge,
},
},
}Left- Distance from left edgeTop- Distance from top edgeRight- Distance from right edgeBottom- Distance from bottom edgeWidth- Width of child (optional)Height- Height of child (optional)
Align a child within available space.
&widgets.Align{
Alignment: widgets.AlignmentBottomRight,
Child: &widgets.Text{Data: "Bottom Right"},
}Predefined alignments:
AlignmentTopLeft,AlignmentTopCenter,AlignmentTopRightAlignmentCenterLeft,AlignmentCenter,AlignmentCenterRightAlignmentBottomLeft,AlignmentBottomCenter,AlignmentBottomRight
Custom alignment:
widgets.AlignmentValue{
X: 0.5, // -1.0 (left) to 1.0 (right)
Y: -0.5, // -1.0 (top) to 1.0 (bottom)
}WidthFactor- Multiply child width to get our widthHeightFactor- Multiply child height to get our height
// Container sized to 2x child size
&widgets.Align{
WidthFactor: floatPtr(2.0),
HeightFactor: floatPtr(2.0),
Alignment: widgets.AlignmentCenter,
Child: child,
}Convenience widget for decoration, padding, margin, and sizing.
&widgets.Container{
Width: floatPtr(200),
Height: floatPtr(100),
Color: goflow.NewColor(100, 149, 237, 255),
Padding: goflow.NewEdgeInsets(16, 12, 16, 12),
Margin: goflow.NewEdgeInsets(8, 8, 8, 8),
Child: &widgets.Text{Data: "Styled Container"},
}Width- Fixed widthHeight- Fixed heightColor- Background colorPadding- Inner spacingMargin- Outer spacingChild- Child widget
&widgets.Container{
Color: goflow.NewColor(255, 255, 255, 255),
Padding: goflow.NewEdgeInsets(16, 16, 16, 16),
Margin: goflow.NewEdgeInsets(8, 8, 8, 8),
Child: &widgets.Column{
Children: []goflow.Widget{
&widgets.Text{Data: "Title"},
&widgets.Text{Data: "Subtitle"},
},
},
}Center a child widget.
&widgets.Center{
Child: &widgets.Text{Data: "Centered Text"},
}Equivalent to:
&widgets.Align{
Alignment: widgets.AlignmentCenter,
Child: child,
}Add padding around a child.
&widgets.Padding{
Padding: goflow.NewEdgeInsets(16, 16, 16, 16),
Child: myWidget,
}Or use Container:
&widgets.Container{
Padding: goflow.NewEdgeInsets(16, 16, 16, 16),
Child: myWidget,
}Create padding values:
// Uniform padding
goflow.NewEdgeInsets(16, 16, 16, 16) // left, top, right, bottom
// Symmetric padding
goflow.NewEdgeInsets(16, 8, 16, 8) // horizontal: 16, vertical: 8
// Zero padding
goflow.ZeroEdgeInsets()Fixed size container (part of Container functionality).
width := 100.0
height := 50.0
&widgets.Container{
Width: &width,
Height: &height,
Child: myWidget,
}Fixed height spacer:
height := 20.0
&widgets.Container{
Height: &height,
}Constrain child size:
maxWidth := 300.0
&widgets.Container{
Width: &maxWidth,
Child: &widgets.Text{Data: "Constrained width"},
}Make children expand to fill available space in Row/Column.
Fill remaining space (tight fit):
&widgets.Row{
Children: []goflow.Widget{
fixedWidget,
&widgets.Expanded{
Child: flexibleWidget, // Takes remaining space
},
anotherFixedWidget,
},
}Allow flexibility (loose fit):
&widgets.Column{
Children: []goflow.Widget{
&widgets.Flexible{
Flex: 2,
Fit: widgets.FlexFitLoose,
Child: widget1, // Can be smaller than allocated space
},
&widgets.Flexible{
Flex: 1,
Fit: widgets.FlexFitTight,
Child: widget2, // Must fill allocated space
},
},
}Flex- Flex factor (default 1)Fit- How to fit child (FlexFitLooseorFlexFitTight)
&widgets.Row{
Children: []goflow.Widget{
&widgets.Expanded{
Flex: 1,
Child: leftColumn,
},
&widgets.Expanded{
Flex: 2,
Child: mainColumn,
},
&widgets.Expanded{
Flex: 1,
Child: rightColumn,
},
},
}Empty space in flex layouts (Row/Column).
&widgets.Row{
Children: []goflow.Widget{
leftWidget,
widgets.NewSpacer(), // Pushes widgets apart
rightWidget,
},
}Equivalent to:
&widgets.Expanded{
Child: &widgets.Container{}, // Empty container
}&widgets.Row{
Children: []goflow.Widget{
material.NewButton(child1, onPressed1),
widgets.NewSpacer(),
material.NewButton(child2, onPressed2),
widgets.NewSpacer(),
material.NewButton(child3, onPressed3),
},
}Center horizontally in Column:
&widgets.Column{
CrossAxisAlign: widgets.CrossAxisCenter,
Children: children,
}Center vertically in Row:
&widgets.Row{
CrossAxisAlignment: widgets.CrossAxisCenter,
Children: children,
}Center both axes:
&widgets.Center{
Child: myWidget,
}Space between items:
&widgets.Column{
Children: []goflow.Widget{
item1,
&widgets.Container{Height: floatPtr(16)}, // 16px spacer
item2,
},
}Or use MainAxisAlignment:
&widgets.Column{
MainAxisAlign: widgets.MainAxisSpaceBetween,
Children: children,
}If content overflows, wrap in SingleChildScrollView:
&widgets.SingleChildScrollView{
Child: &widgets.Column{
Children: manyChildren,
},
}