flutter_multi_split_layout
A Flutter widget for creating resizable, multi-panel split layouts — similar to VS Code or IDE-style panel systems. Users can split panels horizontally or vertically, drag dividers to resize, and remove panels. The layout state can be serialized to/from JSON.
Features
- Split panels horizontally or vertically at any depth
- Drag-to-resize dividers between panels
- Remove panels with a single click
- Edit / View mode — disable editing for end-users with
isEditable: false - JSON serialization — save and restore the full layout tree
- Customizable appearance — divider color, thickness, hover color, panel border color, and border radius
Getting started
Add the dependency to your pubspec.yaml:
dependencies:
flutter_multi_split_layout: ^0.0.1
Then run:
flutter pub get
Usage
Basic example
import 'package:flutter_multi_split_layout/flutter_multi_split_layout.dart';
class MyScreen extends StatefulWidget {
const MyScreen({super.key});
@override
State<MyScreen> createState() => _MyScreenState();
}
class _MyScreenState extends State<MyScreen> {
final controller = LayoutController();
@override
Widget build(BuildContext context) {
return MultiSplitLayout(
controller: controller,
itemBuilder: (context, contentId) {
return Center(child: Text(contentId ?? 'Empty panel'));
},
);
}
}
Customizing appearance
MultiSplitLayout(
controller: controller,
dividerThickness: 6.0,
dividerColor: Colors.blueGrey,
hoverColor: Colors.red,
leafBorderColor: Colors.grey.shade200,
borderRadius: 8.0,
itemBuilder: (context, contentId) {
return MyContentWidget(id: contentId);
},
);
View-only mode (no editing)
MultiSplitLayout(
controller: controller,
isEditable: false,
itemBuilder: (context, contentId) => MyContentWidget(id: contentId),
);
Save and restore layout from JSON
// Save
final Map<String, dynamic> json = controller.toJson();
// Restore
final restoredController = LayoutController.fromJson(json);
Programmatic control
// Split a specific panel
controller.splitNode('root', Axis.horizontal);
// Update divider ratio (0.0 – 1.0)
controller.updateRatio('root_split_123', 0.35);
// Remove a panel
controller.removeNode('root_1_123');
API Reference
MultiSplitLayout
| Parameter | Type | Default | Description |
|---|---|---|---|
controller |
LayoutController |
required | Controls the layout tree |
itemBuilder |
Widget Function(BuildContext, String?) |
required | Builds the content of each leaf panel |
isEditable |
bool |
true |
Shows/hides split and delete controls |
dividerThickness |
double |
8.0 |
Width/height of the drag divider |
dividerColor |
Color? |
Colors.black87 |
Color of the divider |
hoverColor |
Color? |
Colors.red |
Highlight color when hovering over delete |
leafBorderColor |
Color? |
Colors.grey.shade300 |
Border color around each panel |
borderRadius |
double? |
0 |
Corner radius of panels and the layout root |
LayoutController
| Member | Description |
|---|---|
LayoutController({LayoutNode? initialNode}) |
Creates a controller, optionally with an existing tree |
LayoutController.fromJson(Map<String, dynamic>) |
Restores a controller from a JSON map |
toJson() |
Serializes the layout tree to a JSON map |
splitNode(String id, Axis direction) |
Splits the panel with the given id |
updateRatio(String splitNodeId, double ratio) |
Sets the divider ratio (0.05–0.95) |
removeNode(String id) |
Removes the panel with the given id |
LayoutNode (models)
LeafNode— a single panel with an optionalcontentIdSplitNode— contains two child nodes, a split direction, and a ratio
Example app
A full example is available in the /example directory. It demonstrates:
- Splitting panels in both directions
- Admin/Client mode toggle (
isEditable) - Printing the current layout as JSON
License
MIT — see LICENSE.