Implementing a Flex Playground in FlutterUnit with TolyUI
This article explains how FlutterUnit leverages TolyUI to create an interactive Layout Playground, detailing the data, view, and logic layers of the Flex Playground, including state management, component composition, and code examples for building flexible UI demos.
FlutterUnit simplifies UI construction by using TolyUI, making previously complex features easy to implement. The Layout Playground offers an intuitive, interactive way to experience component layout characteristics, helping developers understand Flutter's layout system.
The Playground is part of the newly added "Layout Treasury" in the Knowledge Collection module, featuring interactive panels such as the Flex Playground that showcase Flex component layout properties.
Data Layer : The Flex Playground maintains state through a FlexAttr class that stores Flex properties and a DisplayItem class for colored blocks. The state includes a list of DisplayItem objects, the selected index, and the current FlexAttr instance.
class FlexAttr {
final Axis direction;
final MainAxisAlignment mainAxisAlignment;
final CrossAxisAlignment crossAxisAlignment;
final MainAxisSize mainAxisSize;
final TextDirection textDirection;
final VerticalDirection verticalDirection;
final TextBaseline textBaseline;
}
class DisplayItem {
final double width;
final double height;
final Color color;
}The state class holds these structures:
class _FlexPlaygroundState extends State
{
List
_data = [];
late FlexAttr _attr;
int _selectIndex = -1;
}View Layer : The left side displays layout results via a FlexDisplay widget, which builds a Flex using the attributes from FlexAttr and maps DisplayItem objects to children. Interaction is handled through GestureDetector callbacks that update the selected index.
class FlexDisplay extends StatelessWidget {
final List
items;
final FlexAttr attr;
final int selectIndex;
final ValueChanged
onSelectChanged;
const FlexDisplay({
super.key,
required this.items,
required this.attr,
required this.selectIndex,
required this.onSelectChanged,
});
@override
Widget build(BuildContext context) {
return Flex(
direction: attr.direction,
mainAxisAlignment: attr.mainAxisAlignment,
crossAxisAlignment: attr.crossAxisAlignment,
mainAxisSize: attr.mainAxisSize,
textDirection: attr.textDirection,
verticalDirection: attr.verticalDirection,
textBaseline: TextBaseline.alphabetic,
children: items.asMap().keys.map((int index) {
bool active = selectIndex == index;
return GestureDetector(
onTap: () => onSelectChanged(index),
child: DisplayPlayItem(item: items[index], selected: active),
);
}).toList(),
);
}
}The right‑hand operation panel uses FlexOpTool to add, delete, or reset blocks, delegating state changes through callbacks such as onAddBox , onDelete , and onReset . Selectors like TolySelect and ItemSelector provide dropdown menus for enum properties.
class FlexOpTool extends StatefulWidget {
final ValueChanged
onAddBox;
final VoidCallback onDelete;
final VoidCallback onReset;
final FlexAttr attr;
final ValueChanged
onAttrChange;
}Data Logic Layer : Interaction methods modify the state lists and attributes. For example, _onAddBox creates a new DisplayItem with a random color, _deleteSelectIndex removes the selected block, and _reset restores initial data.
void _onAddBox(Size size) {
int index = _data.length + 1;
Color color = kColors[index % kColors.length];
_data.add(DisplayItem(width: size.width, height: size.height, color: color));
setState(() {});
}
void _deleteSelectIndex() {
if (_selectIndex < 0 || _selectIndex >= _data.length) {
$message.warning(message: 'Please select a block to delete!');
return;
}
_data.removeAt(_selectIndex);
_selectIndex = -1;
setState(() {});
}
void _reset({bool init = false}) {
_attr = FlexAttr(direction: Axis.horizontal);
_data = [
DisplayItem(width: 20, height: 20, color: kColors[0]),
DisplayItem(width: 10, height: 80, color: kColors[1]),
DisplayItem(width: 40, height: 30, color: kColors[2]),
DisplayItem(width: 60, height: 20, color: kColors[3]),
];
_selectIndex = -1;
if (init) return;
setState(() {});
}By managing state data, constructing components, handling interaction events, and updating data, developers can easily extend the Playground to support additional layout widgets such as Wrap and Stack. The article encourages exploring the Layout Playground to deepen understanding of Flutter's layout system.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.