multi_split_view

repository·master·Indexed 41 days ago

https://github.com/caduandrade/multi_split_view

A Flutter widget package for implementing complex layouts with multiple horizontal or vertical split panes. It supports flex-based and fixed-size configurations, customizable dividers via DividerBuilder, and programmatic state management using MultiSplitViewController.

Tokens
3K
Snippets
10
Records
14
Agent score
51%

What's inside multi_split_view

  1. Overview of Multi split view

    master
    The multi_split_view package provides a Flutter widget that allows for creating horizontal or vertical split views with multiple panes. It supports configurable sizing (using either flex or fixed sizes) for each child, is highly customizable, and includes a 'pushing dividers' feature.
  2. Create a split layout with MultiSplitView

    master

    The MultiSplitView widget provides a way to create horizontal or vertical split layouts in Flutter. You can specify the orientation using the axis property (defaults to Axis.horizontal) and provide a list of initialAreas to define the starting layout. You can also provide a MultiSplitViewController to programmatically control the areas.

    Key features include:

    • Custom Area Building: Use the builder property to define how each area is rendered.
    • Custom Dividers: Use dividerBuilder to provide a custom widget for the dividers between areas.
    • Interaction Callbacks: Listen to divider events like onDividerTap, onDividerDoubleTap, and drag events (onDividerDragStart, onDividerDragUpdate, onDividerDragEnd).
    • Sizing Policies: Control how areas behave when they overflow or underflow the available space using sizeOverflowPolicy, sizeUnderflowPolicy, and minSizeRecoveryPolicy.
    MultiSplitView(
      axis: Axis.horizontal,
      initialAreas: [
        Area(id: 'area1', weight: 1.0),
        Area(id: 'area2', weight: 2.0),
      ],
      builder: (context, area) {
        return Container(
          color: area.id == 'area1' ? Colors.red : Colors.blue,
          child: Text('Area ${area.id}'),
        );
      },
    );
  3. Configure theme using MultiSplitViewTheme

    master

    Use the MultiSplitViewTheme widget to apply a specific MultiSplitViewThemeData configuration to all descendant MultiSplitView widgets in the widget tree. This allows you to centralize styling and behavior settings for your split views.

    To use it, wrap your widget tree (or a specific subtree) with MultiSplitViewTheme and provide a data object of type MultiSplitViewThemeData.

    MultiSplitViewTheme(
      data: MultiSplitViewThemeData(
        // Configure your theme properties here
      ),
      child: YourSplitViewWidget(),
    )
  4. Customize MultiSplitView appearance with MultiSplitViewThemeData

    master

    Use MultiSplitViewThemeData to define the visual configuration for a MultiSplitView widget subtree. This allows you to control the thickness of the dividers, the clickable area around them, and the painter used to draw the dividers.

    Properties

    • dividerThickness: A double representing the thickness of the divider. Must be a non-negative value. Defaults to 10.0.
    • dividerHandleBuffer: A double defining the additional clickable area around the divider. Must be a non-negative value. Defaults to 0.0.
    • dividerPainter: An optional DividerPainter used to customize how the divider is drawn.

    Constraints

    Both dividerThickness and dividerHandleBuffer must be non-negative. Providing a negative value will throw an ArgumentError.

    MultiSplitViewThemeData( 
      dividerThickness: 5.0, 
      dividerHandleBuffer: 2.0, 
      dividerPainter: MyCustomPainter(),
    );
  5. Configure an Area in MultiSplitView

    master

    An Area represents a single split section within a MultiSplitView. You can define how an area occupies space using either a fixed size (in pixels) or a flex factor.

    Constraints:

    • You cannot provide both size and flex for the same area. If neither is provided, flex defaults to 1.
    • You can set min and max boundaries for both size and flex to prevent an area from becoming too small or too large.
    • Each area has a unique id used for maintaining state during layout reconfigurations. If you don't provide one, a unique AreaId is generated.
    • You can attach arbitrary data to an area for use within your application logic.
    • You can provide an AreaWidgetBuilder via the builder property to define how the area's content is constructed.
    Area(
      size: 200.0, // Fixed width/height in pixels
      min: 100.0,  // Minimum size allowed
      max: 500.0,  // Maximum size allowed
      id: 'sidebar',
      data: myCustomData,
      builder: (context, area) => MySidebarWidget(data: myCustomData),
    );
    
    // OR using flex
    Area(
      flex: 2,
      min: 1.0,
      id: 'main-content',
    );
  6. Use MultiSplitViewController to manage split view state

    master

    The MultiSplitViewController is used to programmatically control and manage the state of a MultiSplitView. It allows you to add, remove, and access Area objects that define the split layout.

    Important: Do not share a single MultiSplitViewController instance between multiple MultiSplitView widgets.

    // Initialize the controller with an initial list of areas
    final controller = MultiSplitViewController(areas: [
      Area(flex: 1),
      Area(flex: 2),
    ]);
    
    // Access the current areas
    List<Area> currentAreas = controller.areas;
    
    // Get the count of areas
    int count = controller.areasCount;
  7. Use AreaDataModifier to automatically update Area data

    master

    The AreaDataModifier is a typedef for a function that allows you to automatically set or modify the data attribute of an Area based on its current state and index. This is useful for injecting custom metadata into areas during layout updates.

    typedef AreaDataModifier = dynamic Function(Area area, int index);

    You can assign this modifier to the areaDataModifier property of the MultiSplitViewController.

    // Define a modifier that assigns custom data to each area
    MultiSplitViewController controller = MultiSplitViewController(
      areaDataModifier: (Area area, int index) {
        return {'id': 'area_$index', 'custom_prop': 'value'};
      },
    );
    
    // You can also update the modifier later
    controller.areaDataModifier = (area, index) => {'index': index};
  8. Access the current MultiSplitViewTheme via MultiSplitViewTheme.of()

    master

    To retrieve the current theme configuration from the nearest MultiSplitViewTheme ancestor, use the static MultiSplitViewTheme.of(BuildContext context) method.

    If no MultiSplitViewTheme is found in the context, it returns a default MultiSplitViewThemeData instance.

    MultiSplitViewThemeData currentTheme = MultiSplitViewTheme.of(context);
  9. Create a modified copy of an Area

    master

    Use the copyWith method to create a new Area instance based on an existing one, replacing specific fields while keeping the rest unchanged. This is useful for immutable-style updates or generating variations of a layout configuration.

    Area newArea = existingArea.copyWith(
      size: 400.0,
      data: 'new data',
    );
  10. Manage areas with MultiSplitViewController

    master

    You can dynamically modify the layout of a MultiSplitView using the following methods on the MultiSplitViewController:

    • addArea(Area area): Adds a new Area to the split view.
    • removeAreaAt(int index): Removes the Area at the specified index.
    • getArea(int index): Retrieves the Area object at the given index.
    • set areas(List<Area> areas): Replaces the entire set of areas with a new list.
    // Add a new area
    controller.addArea(Area(flex: 1));
    
    // Remove an area at a specific index
    controller.removeAreaAt(0);
    
    // Replace all areas
    controller.areas = [
      Area(flex: 1),
      Area(flex: 1),
    ];
  11. Manage Area size and flex properties

    master

    The Area class extends ChangeNotifier, allowing you to dynamically update its dimensions. When you update size, flex, min, or max, the area notifies its listeners to trigger a rebuild.

    Important Rules:

    • Setting size while flex is non-null (or vice versa) will throw an ArgumentError.
    • Setting min or max values that result in max < min will throw an ArgumentError.
    // Example of dynamic updates
    void resizeArea(Area area) {
      area.size = 300.0; // Updates size and notifies listeners
      area.flex = 1.0;  // Updates flex and notifies listeners
    }
  12. Configure MultiSplitView properties

    master

    The MultiSplitView constructor accepts several configuration options to control layout behavior and interaction:

    PropertyTypeDescription
    axisAxisThe orientation of the split view. Defaults to Axis.horizontal.
    controllerMultiSplitViewController?Controller for managing areas.
    initialAreasList<Area>?The initial set of areas to display.
    builderAreaWidgetBuilder?A builder function to create the widget for each area.
    dividerBuilderDividerBuilder?A builder function to create custom divider widgets.
    resizableboolWhether the dividers can be dragged. Defaults to true.
    pushDividersboolIf true, dragging a divider can push other dividers. Defaults to false.
    sizeOverflowPolicySizeOverflowPolicyPolicy for handling overflow of non-flexible areas.
    sizeUnderflowPolicySizeUnderflowPolicyPolicy for handling cases where non-flexible areas are smaller than available space.
    minSizeRecoveryPolicyMinSizeRecoveryPolicyOrder in which minimum sizes of areas are recovered.
    antiAliasingWorkaroundboolEnables a workaround for rounding coordinates to integer values to minimize jitter.
    fallbackWidthdoubleWidth used in unbounded width situations. Defaults to 500.
    fallbackHeightdoubleHeight used in unbounded height situations. Defaults to 500.
    areaClipBehaviorClipHow each area is clipped. Defaults to Clip.hardEdge.