GridNavigator class

Manages 2D grid navigation with predictable wrapping semantics.

When to use

Reach for GridNavigator when you render collections as a matrix (card grids, emoji pickers, icon launchers, split panes). It keeps track of the focused cell, handles wrapping in every direction, and keeps your widgets free from manual row/column arithmetic.

Layout strategies

  • Call the default constructor when you know the number of columns up front
  • Use GridNavigator.responsive to derive a column count from terminal width, cell width, and separators—perfect for adaptive layouts
  • Use GridNavigator.balanced to quickly build a near-square grid without thinking about math

Examples

// Fixed columns (12 items shown as 3 rows of 4)
final grid = GridNavigator(itemCount: 12, columns: 4);
grid.moveRight(); // wraps to the next row when hitting an edge
grid.moveDown();  // wraps from bottom row back to top

// Responsive layout driven by terminal width
final adaptiveGrid = GridNavigator.responsive(
  itemCount: items.length,
  cellWidth: 20,
  availableWidth: terminalWidth,
);

Integration hints

Pair the navigator with a SelectionController (single or multi) to keep the focused cell and the user selection in sync:

final nav = GridNavigator(itemCount: icons.length, columns: 6);
final sel = SelectionController.multi();

KeyBindings.arrowKeys(
  onLeft: nav.moveLeft,
  onRight: nav.moveRight,
  onUp: nav.moveUp,
  onDown: nav.moveDown,
  onSelect: () => sel.toggle(nav.focusedIndex),
);

The navigator only knows about indices, so it is agnostic to the type of the widgets/items you render—ideal for downstream consumers on pub.dev.

Constructors

GridNavigator({required int itemCount, required int columns, int initialIndex = 0})
Creates a grid navigation with fixed column count.
GridNavigator.balanced({required int itemCount, int? cellWidth, int? availableWidth, int? maxColumns, int initialIndex = 0})
Creates a balanced grid (roughly square).
factory
GridNavigator.responsive({required int itemCount, required int cellWidth, required int availableWidth, int? maxColumns, int initialIndex = 0, int separatorWidth = 1, int prefixWidth = 2})
Creates a grid navigation with responsive column calculation.
factory

Properties

columns int
Number of columns.
getter/setter pair
focusedColumn int
Current focused column (0-indexed).
no setter
focusedIndex int
Current focused index.
no setter
focusedRow int
Current focused row (0-indexed).
no setter
hashCode int
The hash code for this object.
no setterinherited
isEmpty bool
Whether the grid is empty.
no setter
isNotEmpty bool
Whether the grid is not empty.
no setter
itemCount int
Total number of items.
getter/setter pair
layout GridLayout
Returns layout information for rendering.
no setter
rows int
Number of rows (calculated from item count and columns).
no setter
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

isFocused(int index) bool
Checks if an index is currently focused.
jumpTo(int index) → void
Jumps to a specific index (clamped to valid range).
jumpToCell(int row, int col) → void
Jumps to a specific cell by row and column.
jumpToFirst() → void
Jumps to the first item.
jumpToLast() → void
Jumps to the last item.
moveDown() → void
Moves focus down by one row with wrapping.
moveLeft() → void
Moves focus left by one cell with wrapping.
moveRight() → void
Moves focus right by one cell with wrapping.
moveUp() → void
Moves focus up by one row with wrapping.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
reset({int initialIndex = 0}) → void
Resets navigation to initial state.
rowsOf<T>(List<T> items) Iterable<GridRow<T>>
Iterates over rows, providing items for each row.
toString() String
A string representation of this object.
override

Operators

operator ==(Object other) bool
The equality operator.
inherited