DEV Community

Cover image for Getting to know Flutter: List Lazy loading
TheOtherDev/s
TheOtherDev/s

Posted on

4 1

Getting to know Flutter: List Lazy loading

Sometimes you may need to handle of hundreds of data received from an API or fetched from a DB. ListView lazy load is absolutely what you need to maintain a responsive layout.

First of all, let’s begin doing a simple setup for our example:

  • Declare a Stateful Widget,
  • Add a ScrollController,
  • Add a ListView,
  • Assign the _controller as controller of our ListView.
final ScrollController _controller = ScrollController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Lazy list'),
      ),
      body: ListView.builder(
        controller: _controller,
        itemCount: 0,
        itemBuilder: (context, index) {
          return;
        },
      ),
    );
  }
Enter fullscreen mode Exit fullscreen mode

Listening to the Scroll Event

Let’s add a listener to our _controller Inside initState method, he will be responsible to handle the pagination of our ListView.

@override
  void initState() {
    _controller.addListener(_onScroll);
    super.initState();
  }

  _onScroll() {

  }
Enter fullscreen mode Exit fullscreen mode

Since we added a listener to our controller we must call dispose() method too to remove it from memory once we dismiss the current screen.

@override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
Enter fullscreen mode Exit fullscreen mode

Let’s add two parameters, one for the loading state and one for the data, I’ll call it _dummy and it will be List of Strings, but you can use any type of object.

class _MyHomePageState extends State<MyHomePage> {
  final ScrollController _controller = ScrollController();

  bool _isLoading = false;
  List<String> _dummy = List.generate(20, (index) => 'Item $index');
Enter fullscreen mode Exit fullscreen mode

Now let’s set up our ListView.

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('lazy list'),
      ),
      body: ListView.builder(
        controller: _controller,
        itemCount: _isLoading ? _dummy.length + 1 : _dummy.length,
        itemBuilder: (context, index) {
          if (_dummy.length == index)
            return Center(
                child: CircularProgressIndicator()
            );
          return ListTile(
            title: Text(
                _dummy[index]
            )
          );
        },
      ),
    );
  }
Enter fullscreen mode Exit fullscreen mode

When we reach the end of the list we will show a loader as the last element, else we’ll show an element of dummy. Now let’s get back to the scroll thing. The following method shows how to know when the user reaches the bottom of the list, and when he does it we’ll update the _isLoading variable to show the spinner.

_onScroll() {
    if (_controller.offset >=
        _controller.position.maxScrollExtent &&
        !_controller.position.outOfRange) {
      setState(() {
        _isLoading = true;
      });
      _fetchData();
    }
}
Enter fullscreen mode Exit fullscreen mode

Data Fetch

Now let’s simulate an API call or a DB fetch using a more concise Future.delayed:

Future _fetchData() async {
  await new Future.delayed(new Duration(seconds: 2));
}
Enter fullscreen mode Exit fullscreen mode

Just after 2 seconds we will receive the data (whatever it is) and update the state of the widget to reflect the changes.

Future _fetchData() async {
  await new Future.delayed(new Duration(seconds: 2));
  int lastIndex = _dummy.length;

  setState(() {
     _dummy.addAll(
         List.generate(15, (index) => "New Item ${lastIndex+index}")
     );
    _isLoading = false;
  });
}
Enter fullscreen mode Exit fullscreen mode

Using the ScrollController is not so hard, but you can go deeper using the ScrollNotification and more deeper adding animations with CustomScrollView.

Need to check the full code? Nothing easier => GitHub.

AWS Security LIVE! Stream

Stream AWS Security LIVE!

See how AWS is redefining security by design with simple, seamless solutions on Security LIVE!

Learn More

Top comments (0)

Jetbrains image

Build Secure, Ship Fast

Discover best practices to secure CI/CD without slowing down your pipeline.

Read more

👋 Kindness is contagious

Engage with a wealth of insights in this thoughtful article, valued within the supportive DEV Community. Coders of every background are welcome to join in and add to our collective wisdom.

A sincere "thank you" often brightens someone’s day. Share your gratitude in the comments below!

On DEV, the act of sharing knowledge eases our journey and fortifies our community ties. Found value in this? A quick thank you to the author can make a significant impact.

Okay