Flutter ListView and Scrolling

ListView is the most commonly used scrolling list Widget in Flutter, used to display scrollable content lists.


ListView Basic Usage

Example: ListView Basic Usage

// Method 1: children parameter (suitable for a small number of items)
ListView(
  children: [
    ListTile(title: Text('First item')),
    ListTile(title: Text('Second item')),
    ListTile(title: Text('Third item')),
  ],
)

// Method 2: ListView.builder (suitable for large or infinite lists)
ListView.builder(
  itemCount: 100,
  itemBuilder: (context, index) {
    return ListTile(title: Text('Item ${index + 1}'));
  },
)

// Method 3: ListView.separated (with separators)
ListView.separated(
  itemCount: 10,
  separatorBuilder: (context, index) => const Divider(),  // Divider
  itemBuilder: (context, index) {
    return ListTile(title: Text('Item ${index + 1}'));
  },
)

ListView Common Properties

PropertyDescription
scrollDirectionScroll direction, defaults to Axis.vertical (vertical).
reverseWhether to reverse scroll
paddingList padding
itemExtentFixed Item Height for Better Performance
prototypeItemPrototype Item for Calculating Height

Example: Horizontal ListView

// Horizontal scrolling list
SizedBox(
  height: 120,  // Must set height
  child: ListView.builder(
    scrollDirection: Axis.horizontal,  // Horizontal scrolling
    itemCount: 20,
    itemBuilder: (context, index) {
      return Container(
        width: 100,
        margin: const EdgeInsets.symmetric(horizontal: 8),
        color: Colors.blue[100],
        child: Center(
          child: Text('Item $index'),
        ),
      );
    },
  ),
)

GridView - Grid Layout

GridView is used to create two-dimensional grid lists.

Example: GridView Usage

// GridView.count - fixed number of columns
GridView.count(
  crossAxisCount: 3,  // 3 columns
  children: List.generate(20, (index) {
    return Container(
      margin: const EdgeInsets.all(4),
      color: Colors.blue[100],
      child: Center(child: Text('${index + 1}')),
    );
  }),
)

// GridView.builder - dynamic construction
GridView.builder(
  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 4,  // 4 columns
    mainAxisSpacing: 8,  // Vertical spacing
    crossAxisSpacing: 8,  // Horizontal spacing
    childAspectRatio: 1,  // Aspect ratio
  ),
  itemCount: 50,
  itemBuilder: (context, index) {
    return Container(
      color: Colors.green[100],
      child: Center(child: Text('${index + 1}')),
    );
  },
)

// GridView.extent - adaptive column count
GridView.extent(
  maxCrossAxisExtent: 150,  // Maximum column width
  children: List.generate(20, (index) {
    return Container(
      margin: const EdgeInsets.all(4),
      color: Colors.orange[100],
      child: Center(child: Text('${index + 1}')),
    );
  }),
)

Scroll control

Using ScrollController you can control the scroll position.

Example: Scroll Control

class ScrollExample extends StatefulWidget {
  const ScrollExample({super.key});

  @override
  State<ScrollExample> createState() => _ScrollExampleState();
}

class _ScrollExampleState extends State<ScrollExample> {
  // Create scroll controller
  late ScrollController _controller;

  @override
  void initState() {
    super.initState();
    _controller = ScrollController();
    // Listen for scroll events
    _controller.addListener(() {
      print('Scroll position: ${_controller.offset});
    });
  }

  @override
  void dispose() {
    // Dispose controller
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        // Scroll to top button
        ElevatedButton(
          onPressed: () {
            // Scroll to top
            _controller.animateTo(
              0,
              duration: const Duration(milliseconds: 500),
              curve: Curves.easeInOut,
            );
          },
          child: const Text('Scroll to top'),
        ),
        // List
        Expanded(
          child: ListView.builder(
            controller: _controller,  // Bind controller
            itemCount: 100,
            itemBuilder: (context, index) {
              return ListTile(title: Text('Item ${index + 1}'));
            },
          ),
        ),
      ],
    );
  }
}

Slivers Advanced Scrolling

CustomScrollView combined with Slivers can achieve more complex scrolling effects.

Example: Slivers Collapsing Effect

// Scroll view with collapsible app bar
CustomScrollView(
  slivers: [
    // Collapse app bar
    SliverAppBar(
      expandedHeight: 200,  // Expanded height
      pinned: true,  // Fixed at top
      flexibleSpace: FlexibleSpaceBar(
        title: const Text('Collapsible title'),
        background: Container(
          decoration: BoxDecoration(
            gradient: LinearGradient(
              colors: [Colors.blue, Colors.purple],
              begin: Alignment.topLeft,
              end: Alignment.bottomRight,
            ),
          ),
        ),
      ),
    ),
    // List content
    SliverList(
      delegate: SliverChildBuilderDelegate(
        (context, index) => ListTile(title: Text('Item ${index + 1}')),
        childCount: 30,
      ),
    ),
  ],
)

// Grid Sliver
CustomScrollView(
  slivers: [
    const SliverAppBar(
      title: Text('Image Grid'),
      pinned: true,
    ),
    SliverGrid(
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
      ),
      delegate: SliverChildBuilderDelegate(
        (context, index) => Card(
          child: Image.network('https://picsum.photos/200?$index'),
        ),
        childCount: 20,
      ),
    ),
  ],
)

Slivers provide an efficient way to handle a large number of scrolling items; they only render items in the visible area, thus providing good performance.

other extensions