Skip to main content

LayoutBuilder

Builds its child using a callback that receives the parent's layout constraints. This lets you create responsive layouts that adapt to available space.

Basic Usage​

widgets.LayoutBuilder{
Builder: func(ctx core.BuildContext, constraints layout.Constraints) core.Widget {
if constraints.MaxWidth > 600 {
return wideLayout()
}
return narrowLayout()
},
}

Properties​

PropertyTypeDescription
Builderfunc(core.BuildContext, layout.Constraints) core.WidgetCalled during layout with the resolved constraints. Returns the child widget tree. May be nil, which produces a zero-size box.

How It Works​

Drift's pipeline normally runs Build before Layout, so widgets cannot observe constraints at build time. LayoutBuilder bridges this gap by deferring its child building to the layout phase:

  1. During the build phase, LayoutBuilder mounts without building any children.
  2. During layout, the render object receives constraints from its parent and invokes the builder callback.
  3. The builder returns a widget tree that is reconciled into the element tree.
  4. The resulting child is laid out with the same constraints.

The builder is re-invoked when constraints change or when the widget is updated (for example, because an inherited dependency changed).

Common Patterns​

Responsive Breakpoints​

Switch between layouts based on available width:

widgets.LayoutBuilder{
Builder: func(ctx core.BuildContext, c layout.Constraints) core.Widget {
if c.MaxWidth >= 600 {
return tabletLayout(ctx)
}
return phoneLayout(ctx)
},
}

Adaptive Grid Columns​

Choose a column count based on the container width:

widgets.LayoutBuilder{
Builder: func(ctx core.BuildContext, c layout.Constraints) core.Widget {
columns := int(c.MaxWidth) / 200
if columns < 1 {
columns = 1
}
return buildGrid(columns, items)
},
}

Nested Inside a SizedBox​

LayoutBuilder receives whatever constraints its parent provides. Wrapping it in a constraining widget narrows the constraints the builder sees:

widgets.Center{
Child: widgets.SizedBox{
Width: 300,
Height: 200,
Child: widgets.LayoutBuilder{
Builder: func(ctx core.BuildContext, c layout.Constraints) core.Widget {
// c.MaxWidth == 300, c.MaxHeight == 200
return buildContent(c)
},
},
},
}

When to Use LayoutBuilder​

  • Choosing between different widget trees based on available width or height
  • Computing sizes or column counts from constraints
  • Building content that must know its maximum dimensions before rendering

When you only need to constrain a child to a fixed size, prefer SizedBox instead.