Search code examples
flutterdartflutter-listviewflutter-sliver

Flutter - How to create an infinite scrollable list up and down


I want to create an infinite scrollable list like it is possible to do with ListView.builder :

ListView.builder(
  itemBuilder: (context, index) => Text(index.toString()),
);

But doing so only creates an infinite list in "one direction" (down): index can only be 0 <= index.

I would like to also be able to scroll up which would be equivalent to having an index being possibly negative.

Is there any built-in widget for that? I couldn't find anything, even among the slivers:


Solution

  • You can use CustomScrollView with anchor: 0.5:

    You can look at growthDirection property dartpad example.

    Or here is a simplified example:

    import 'package:flutter/material.dart';
    
    class MyWidget extends StatefulWidget {
      const MyWidget({
        super.key,
      });
    
      @override
      State<MyWidget> createState() => _MyWidgetState();
    }
    
    class _MyWidgetState extends State<MyWidget> {
      final UniqueKey _center = UniqueKey();
    
      final _controller = ScrollController();
    
      @override
      void dispose() {
        _controller.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return CustomScrollView(
          controller: _controller,
          anchor: 0.5,
          center: _center,
          slivers: [
            SliverList.builder(
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text((index + 1).toString()),
                );
              },
            ),
            SliverToBoxAdapter(
              // This sliver will be located at the anchor. The scroll position
              // will progress in either direction from this point.
              key: _center,
              child: const ListTile(
                title: Text('0'),
              ),
            ),
            SliverList.builder(
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text((index + 1).toString()),
                );
              },
            ),
          ],
        );
      }
    }
    
    void main() {
      runApp(
        MaterialApp(
          home: Scaffold(
            body: MyWidget(),
          ),
        ),
      );
    }
    

    I looks like this:

    enter image description here

    and allows you to have an infinite scroll up and down.