Apply Spacing and Dividers Between Widgets in Flutter

Consistent spacing in Flutter UIs is crucial. Manually adding spacers is tedious. This post introduces a utility class to simplify the process and save time.

Published on

2 min read

When building UI with Flutter, one key aspect of a clean and readable layout is the consistent spacing between widgets. Manually adding spacers or dividers can be repetitive and time-consuming. In this post, I will be sharing a utility class that simplifies this process, saving you valuable time.

The SeparatedList class allows us to apply spacing to rows and columns easily. Copy the code, and paste it inside your project.

import 'package:flutter/material.dart';

// For equal spacing separation used in [Row] and [Column].
class SeparatedList {
  /// Insert [SizedBox] separators between each element horizontally
  static List<Widget> horizontal({
    double spacing = 8.0,
    required List<Widget> children,
  }) {
    final separator = SizedBox(width: spacing);
    return custom(separator: separator, children: children);
  }

  /// Insert [SizedBox] separators between each element vertically
  static List<Widget> vertical({
    double spacing = 8.0,
    required List<Widget> children,
  }) {
    final separator = SizedBox(height: spacing);
    return custom(separator: separator, children: children);
  }

  /// Insert custom [Widget] separators between each element
  static List<T> custom<T extends Widget, S extends T>({
    required S separator,
    required List<T> children,
  }) {
    List<T> widgets = [];
    children.asMap().entries.forEach((childEntry) {
      if (childEntry.key > 0) widgets.add(separator);
      widgets.add(childEntry.value);
    });
    return widgets;
  }
}

Horizontal Spacing with SeparatedList

For a row of widgets that require equal horizontal spacing, SeparatedList.horizontal can be used:

Row(   
  children: SeparatedList.horizontal(
    spacing: 8.0,   
    children: [
      Icon(Icons.star),
      Icon(Icons.star),
      Icon(Icons.star),
    ],
  ),
)

This wraps the provided children in a Row widget, inserting a SizedBox with the specified width between each child.

Vertical Spacing with SeparatedList

For columnar layouts, SeparatedList.vertical provides a similar functionality but with vertical spacing:

Column(   
  children: SeparatedList.vertical(
    spacing: 10.0,
    children: [
      Text('First'),
      Text('Second'),
      Text('Third'),
    ],
  ),
)

Each child in the Column will have a SizedBox with the specified height placed between them.

Custom Separators with SeparatedList

You can also pass a custom widget as a separator with SeparatedList.custom:

Row(   
  children: SeparatedList.custom(
    separator: const Icon(Icons.flash_on),
    children: [
      Text('Pow!'),  
      Text('Zap!'),  
      Text('Bam!'),
    ],
  ),
)

Conclusion

Instead of manually adding spacing widgets after each child SeparatedList automatically handles this. It provides a clear and concise way to define consistent spacing between widgets in a Row or Column, which can be especially useful in dynamic layouts where widgets may be conditionally included.

By Encapsulating the spacing logic within a reusable utility class, we can improve code cleanliness and maintainability. I hope this will save you time while you implement your layouts.