Creating Widgets with Builder Functions in Flutter
What is a builder function? 🤔
A builder is a Flutter design pattern in which the construction code of a widget is defined outside of its class. Builder functions are callback interfaces that pass data (often layout-specific) to the parent widget which returns a child based on that data.
Builder functions are used by several built-in widgets such as
ListView.builder
— renders items linearly, passes index to builder function for better control over individual items in the list
GridView.builder
— renders items in a 2D array, passes index to builder function for control of each tile in the grid
LayoutBuilder
— passes constraints of parent for size dependent layouts
Built-in Example (ListView):
List<String> veggies = ['Broccoli', 'Carrot', 'Cucumber'];ListView.builder(
itemCount: veggies.length,
itemBuilder: (context, int index) => Text(veggies[index]),
);
The ListView
above handles layout logic for showing items in a scrollable list and outputs an instance of the builder function at every new line.
Notice the 2 parameters, context
and index
.
The builder function itemBuilder
is simply a function signature which is defined by these 2 types:
// itemBuilder is an instance of IndexedWidgetBuildertypedef IndexedWidgetBuilder = Widget Function(BuildContext context, int index);
Dart’s
typedef
(function-type alias) keyword allows the creation of function signatures which are defined by input parameters alone
Function signatures are used in a widget’s constructor as callback interfaces to separate construction code from the build method and rather be defined per-instance.
The build method is used to define where each instance of the callback should be invoked.
BoardBuilder Example
BoardBuilder(
builder: (context, tileId) {
// draw game piece for tileId
},
),
Below is a board widget which provides a callback for each tile, since game logic exists separately from the board’s layout logic.
Our end result will look something like this:
Step 1: Define a function signature by its input parameters
tileId
is used to identify which game piece to render
Step 2: Define the widget which invokes the builder function
The game board will need to provide 64 alphanumeric ids based on row and column. GridView
can be used to generate the tiles.
builder
is an instance of the BoardWidgetBuilder
function signature which passes ids based on tile position
If we implement the current widget and always return back an empty Container
we have this
Step 3: Implement the builder widget
A Piece
class is used to draw a colored circle depending on some player identifier
Lets also mock-up some game data which is represented as a map from tileId
to the player’s id of the piece on that tile
Finally implement the BoardBuilder
which returns a Piece
if a tileId
is populated, otherwise returns Container
And that’s it! The board layout is now very simple to work with so you can better focus on programming the game logic 🎉
Full source code:
https://github.com/hawkinsjb1/builder-functions-demo