YouTip LogoYouTip

Flutter Listview

Flutter ListView and Scrolling | Beginner's Tutorial

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 small number of items)

ListView(
  children: [
    ListTile(title: Text('Item 1')),
    ListTile(title: Text('Item 2')),
    ListTile(title: Text('Item 3')),
  ],
)

// 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(), // separator line
  itemBuilder: (context, index) {
    return ListTile(title: Text('Item ${index + 1}'));
  },
)

ListView Common Properties

PropertyDescription
scrollDirectionScroll direction, default is Axis.vertical (vertical)
reverseWhether to reverse the scroll direction
paddingList inner padding
itemExtentFixed item height, can improve performance
prototypeItemPrototype item, used to calculate height

Example: Horizontal ListView

// Horizontal scrolling list

SizedBox(
  height: 120, // Must set height
  child: ListView.builder(
    scrollDirection: Axis.horizontal, // Horizontal scroll
    itemCount: 20,
    itemBuilder: (context, index) {
      return Container(
        width: 100,
        margin: const EdgeInsets.symmetric(horizontal: 8),
        color: Colors.blue,
        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,
      child: Center(child: Text('${index + 1}')),
  }),
)

// GridView.builder - Dynamic building

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,
      child: Center(child: Text('${index + 1}')),
    );
  },
)

// GridView.extent - Adaptive number of columns

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

Scroll Control

ScrollController can be used to control the scroll position.

Example: Scroll Control

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

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

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

  @override
  void initState() {
    super.initState();
    _controller = ScrollController();
    // Listen to 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 collapsing app bar

CustomScrollView(
  slivers: [
    // Collapsing app bar
    SliverAppBar(
      expandedHeight: 200, // Expanded height
      pinned: true, // Pin to top
      flexibleSpace: FlexibleSpaceBar(
        title: const Text('Collapsing 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 large numbers of scrollable items, they only render items in the visible area, thus providing good performance.

← Flutter State ManagementFlutter Layout β†’