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.flutter-io.cn.

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