ListView class
A scrollable, keyboard-navigable list of items, vertical by default or horizontal with scrollDirection.
Two ways to populate the list:
ListView(children: [...])— eager. Every child widget is built upfront on each rebuild; the layout/paint pass only visits items that fit in the viewport. Best when you have a bounded set of widgets you already constructed.ListView.builder(itemCount: N, itemBuilder: (context, index, highlighted) {})— lazy. Only items currently within the viewport are mounted as element subtrees; items scroll into/out of the mounted set as the user navigates. Supports variable sizes along the scrolling axis. Best for long lists where most items are off-screen (file pickers, log viewers, completion menus).
When focused, the list handles its main-axis arrows (Up and Down, or Left and Right in a horizontal list), PageUp, PageDown, Home, End, and Enter:
- The arrows move the current item by one, PageUp and PageDown by the number of items in view, and Home and End to the first and last item. A move reports onFocusedItemChanged and scrolls the item into view.
- Enter or a completed click selects the current item via onSelect.
- An arrow or page key pressed on the first item toward the start, or on
the last toward the end, follows edgeBehavior:
containconsumes the key,bubblereturns it to the focus chain so an ancestorKeyBindings(e.g. one coordinating sidebar + main pane focus traversal) can react. From any other item, a page key stops at the first or last item. - A list without a current item (
selectable: false, or a controller with no cursor) scrolls instead: the arrows by one cell and PageUp and PageDown by a viewport, following edgeBehavior once scrolled to an end, while Home and End jump to the start and end.
itemBuilder receives (context, index, highlighted) for each visible item.
The current item remains highlighted when keyboard focus leaves the list.
The controller's ListController.currentIndex identifies that item.
Setting it moves the cursor without selecting an item or taking focus.
All constructors apply the theme's selection style to the current row's text. Plain Text children need no cursor styling. Explicit child styles override that default; the builder flag is available for custom decoration.
- Inheritance
-
- Object
- Widget
- StatefulWidget
- ListView
- Available extensions
Constructors
-
ListView({Key? key, ListController? controller, FocusNode? focusNode, required List<
Widget> children, bool autofocus = false, bool selectable = true, EdgeBehavior edgeBehavior = EdgeBehavior.bubble, void onSelect(int index)?, void onFocusedItemChanged(int index)?, bool scrollbar = false, Axis scrollDirection = Axis.vertical, bool addRepaintBoundaries = true}) -
Eager constructor: build all items upfront from a fixed list
of widgets. Use when you have a bounded set of widgets already
constructed. The current row is highlighted automatically.
const
- ListView.builder({Key? key, ListController? controller, FocusNode? focusNode, required int itemCount, required Widget itemBuilder(BuildContext, int, bool), ListItemKeyBuilder? itemKeyBuilder, bool autofocus = false, bool selectable = true, EdgeBehavior edgeBehavior = EdgeBehavior.bubble, void onSelect(int index)?, void onFocusedItemChanged(int index)?, bool scrollbar = false, Axis scrollDirection = Axis.vertical, bool addRepaintBoundaries = true})
-
Lazy constructor: build items on demand by index, mount only the
visible ones. Each item builder invocation receives a
highlightedflag for styling the current row.const - ListView.separated({Key? key, ListController? controller, FocusNode? focusNode, required int itemCount, required Widget itemBuilder(BuildContext, int, bool), required Widget? separatorBuilder(BuildContext, int), ListItemKeyBuilder? itemKeyBuilder, bool autofocus = false, bool selectable = true, EdgeBehavior edgeBehavior = EdgeBehavior.bubble, void onSelect(int index)?, void onFocusedItemChanged(int index)?, bool scrollbar = false, Axis scrollDirection = Axis.vertical, bool addRepaintBoundaries = true})
-
Lazy constructor with separators — the TUI analogue of Flutter's
ListView.separated.
separatorBuilderis called for each gapi— the space between itemiand itemi + 1, so0 <= i <= itemCount - 2— and may returnnullto omit that gap's separator (e.g. a day divider shown only when the day actually changes).const
Properties
- addRepaintBoundaries → bool
-
Whether each item gets its own RepaintBoundary, so an update inside one
item (a row's setState, a line of streaming output) repaints only that
item rather than the whole list. Items stay interactive and accessible
either way.
final
- autofocus → bool
-
Whether to request focus on first mount.
final
-
children
→ List<
Widget> ? -
Pre-built widgets (eager form). Mutually exclusive with
itemCount / itemBuilder.
final
- controller → ListController?
-
External controller. If null, the widget creates its own and
disposes it on unmount.
final
- edgeBehavior → EdgeBehavior
-
How main-axis arrows and wheel gestures behave at an edge.
Cross-axis input can reach other controls or a surrounding scroll view.
final
- effectiveItemCount → int
-
Effective number of items, regardless of which constructor was
used. Returns
children!.lengthfor eager,itemCount!for lazy.no setter - focusNode → FocusNode?
-
External FocusNode. Provide one when a parent needs to drive
focus (e.g. Tab cycling between sidebar and main pane). If null,
the widget creates its own and disposes it on unmount.
final
- hashCode → int
-
The hash code for this object.
no setterinherited
- itemBuilder → Widget Function(BuildContext context, int index, bool highlighted)?
-
Per-index widget builder (lazy form). Mutually exclusive with
children. Invoked with
(context, index, highlighted).final - itemCount → int?
-
Number of items (lazy form). Mutually exclusive with children.
final
- itemKeyBuilder → ListItemKeyBuilder?
-
Returns a stable key for the data item at each index. Supply it when items
can move (prepends, removals, filters, reorders) so the current item, the
scroll position, and the state of mounted items follow each item rather
than its index. Keys must be unique within the list and have stable
equality and hash codes; a duplicate key throws a StateError.
final
- key → Key?
-
finalinherited
- onFocusedItemChanged → void Function(int index)?
-
Reports user input moving the cursor to a different item.
final
- onSelect → void Function(int index)?
-
Selects an item on Enter or a completed click, including repeated choices.
Browsing, scrolling, and controller writes do not call this. Empty lists
and lists without a cursor cannot select an item.
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- scrollbar → bool
-
When true, wrap the list in a Scrollbar gutter that reflects the
visible item range and lets the mouse drag/click to scroll. A one-line
opt-in: the bar shares this list's controller, so there is nothing extra
to wire. See Scrollbar.list.
final
- scrollDirection → Axis
-
Layout and scrolling axis. Items are measured at their natural extent
along this axis and constrained to the viewport on the other axis.
final
- selectable → bool
-
Whether the list owns a row cursor and selects rows with click or Enter.
False keeps it scrollable without a row cursor. Interactive
child widgets keep their own input behavior.
final
- separatorBuilder → Widget? Function(BuildContext context, int index)?
-
Per-gap separator builder (ListView.separated form). Called with
(context, i)for the gap between itemiand itemi + 1; may returnnullto omit that separator. Null for the eager and ListView.builder forms.final
Methods
-
animate(
{Duration? duration, Curve? curve, Object? trigger, bool repeat = false}) → Animate -
Available on Widget, provided by the AnimateExtension extension
Starts an Animate chain over this widget.duration/curveapply to the whole chain. With notriggerit plays on mount; with a non-null trigger it rests on mount and replays whenever the token changes. -
createElement(
) → StatefulElement -
Creates the Element that will mount this widget into the tree.
inherited
-
createState(
) → State< ListView> -
Creates the mutable state for this widget at the current location in
the tree. Called exactly once per StatefulElement instance.
override
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited