Is it possible for a ListView to loop back to the beginning of a finite list to create infinite scrolling in Flutter?

Viewed 467

I have a settings screen where the user can select 1 of 5 possible images which are laid out in a horizontal ListView. The images are too wide for the screen so the ListView scrolls horizontally.

I am going for a 'lazy Susan' effect where if you keep scrolling left, it just infinitely scrolls through the same 5 options (A B C D E A B C D E A B C...).

Is it possible to set up infinite scrolling on a finite list?

I've spent ages researching but infinite scrolling only seems to be a concept when pulling from the web or generating content programmatically and I just want to infinitely scroll through my 5 items...

3 Answers

Just use ListView.builder with a builder callback returns the same items in a loop. For example:

ListView.builder(
  itemBuilder: (buildContext, index) {
    return listOfWidgets[index % listOfWidgets.length];
  },
),

You can use PageView.builder or ListView.builder(just swap Pageview. builder with Listview.builder & no need to change controller) and initialPageNumber represet how many time you can scroll back (backward scroll) and forward scroll is infinite

class MyHomePage extends StatefulWidget {
      const MyHomePage({
        Key? key,
      }) : super(key: key);
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      final List<Container> yourWidgets = [1, 2, 3, 4, 5]
          .map((e) => Container(
                width: 200,
                height: 200,
                margin: const EdgeInsets.symmetric(horizontal: 5.0),
                color: Colors.blue,
                child: Text(
                  'text $e',
                ),
              ))
          .toList();
    
      final initialPageNumber = 1000; //how many times you can scroll back
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          body: SizedBox(
            height: 200,
            child: PageView.builder(
              scrollDirection: Axis.horizontal,
              controller: PageController(
                initialPage: initialPageNumber,
                viewportFraction: 0.2,
              ),
              itemBuilder: (ctx, i) {
                return yourWidgets[((i - initialPageNumber) < 0
                        ? (i - initialPageNumber) + yourWidgets.length
                        : (i - initialPageNumber)) %
                    yourWidgets.length];
              },
            ),
          ),
          // This trailing comma makes auto-formatting nicer for build methods.
        );
      }
    }
Related