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 optional contentId
  • SplitNode — 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.