How to load more items to a list when reach the bottom of results flutter

2,365

Solution 1

You have to add another 10 data to the crtLap.loadList(subMenu, 20) and call setState inside the scrollListener to rebuild the widget about the changes.

var data = crtLap.loadList(subMenu, 10);

scrollListener() async {
  if (scrollController.position.maxScrollExtent == scrollController.offset) {
    setState((){
       data = crtLap.loadList(subMenu, 20);
     });
  }
}

and use this data field to the FutureBuilder directly,

loadList(submenu ,callback, context, deviceSize){
 return FutureBuilder(
   future: data,
    builder: (ctx, snapshot) {
    .....
  ...
..
}

Solution 2

Infinite Scrolling in ListView

I have achieved this case by using the local field instead of getting data from firebase. Hope it will give you some idea.

import 'package:flutter/material.dart';

class ListViewDemo extends StatefulWidget {
  ListViewDemo({Key key}) : super(key: key);

  @override
  _ListViewDemoState createState() => _ListViewDemoState();
}

class _ListViewDemoState extends State<ListViewDemo> {
  ScrollController controller;
  int count = 15;

  @override
  void initState() {
    super.initState();
    controller = ScrollController()..addListener(handleScrolling);
  }

  void handleScrolling() {
    if (controller.offset >= controller.position.maxScrollExtent) {
      setState(() {
        count += 10;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('List view'),
      ),
      body: ListView.builder(
        controller: controller,
        itemCount: count,
        itemBuilder: (BuildContext context, int index) {
          return ListTile(
            title: Text('Item $index'),
          );
        },
      ),
    );
  }

  @override
  void dispose() {
    controller.removeListener(handleScrolling);
    super.dispose();
  }
}
Share:
2,365
Admin
Author by

Admin

Updated on December 27, 2022

Comments

  • Admin
    Admin over 1 year

    I have the code below which feed a list with 10 results from firebase. In this case it shows only the 10 items, now I wanna, when user gets the bottom of results, it loads more 10 items and add it to the list. I already have the scrollController and it works.. I receive the log "LOAD HERE" when I get the bottom of the results.

    My doubt is how to add the new 10 items in the list?

    scrollListener() async {
        if (scrollController.position.maxScrollExtent == scrollController.offset) {
          print('LOAD HERE');
        
        }
      }
    
      @override
      void initState() {
        scrollController.addListener(scrollListener);
        super.initState();
      }
    
      @override
      void dispose() {
        scrollController.removeListener(scrollListener);
        super.dispose();
      }
    
      loadList(submenu ,callback, context, deviceSize){
        return FutureBuilder(
          future: ctrlLab.loadList(submenu, 10),
          builder: (ctx, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return Center(child: CircularProgressIndicator());
            } else if (snapshot.error != null) {
              print(snapshot.error);
              return Center(child: Text('ERROR!'));
            }else {
              return GridView.builder(
                padding: EdgeInsets.all(10.0),
                controller: scrollController,
                itemCount: snapshot.data.length,
                itemBuilder: (ctx, i) {
                  Item item = snapshot.data[i];
                  if (i < snapshot.data.length) {
                    return Dismissible(
                      key: UniqueKey(),
                      direction: DismissDirection.endToStart,
                      background: Container(
                        padding: EdgeInsets.all(10.0),
                        color: Colors.grey[800],
                        child: Align(
                          alignment: AlignmentDirectional.centerEnd,
                          child: Icon(
                            Icons.delete,
                            color: Colors.white,
                            size: 40,
                          ),
                        ),
                      ),
                      onDismissed: (DismissDirection direction) {
                        ctrl.onDismissed(callback, item);
                      },
                      child: GestureDetector(
                        child: Card(
                          elevation: 5.0,
                          child: Padding(
                            padding: EdgeInsets.all(10.0),
                            child: GridTile(
                              child: Hero(
                                tag: "${item}",
                                child: item.imageUrl == null
                                    ? setIconLab(item)
                                    : CachedNetworkImage(
                                  fit: BoxFit.cover,
                                  imageUrl: setIconLab(item),
                                  placeholder: (ctx, url) =>
                                      Center(child: CircularProgressIndicator()),
                                  errorWidget: (context, url, error) =>
                                      Image.asset('assets/images/noPhoto.jpg',
                                          fit: BoxFit.cover),
                                ),
                              ),
                              footer: Container(
                                padding: EdgeInsets.all(8.0),
                                color: Colors.white70,
                                child: Column(
                                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                  children: [
                                    Text(
                                      item.name
                                      ),
                                    ),
                                  ],
                                ),
                              ),
                            ),
                          ),
                        ),
                      ),
                    );
    
                  }
                },
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCountAndLoading(
                  itemCount: snapshot.data.length + 1,
                  crossAxisCount: deviceSize.width < 600 ? 2 : 3,
                  childAspectRatio: 0.7,
                  crossAxisSpacing: 10.0,
                  mainAxisSpacing: 10.0,
                ),
              );
            }
          },
        );
      }
    
    • Amit Kumar
      Amit Kumar about 3 years
      Use Notification Listener widget it would be more efficient way and listen to scrollnotifications when it reaches max extent use a method to add more data in list used by future builder , here is example
  • Admin
    Admin about 3 years
    This reloads the list completely... I wanna add items to the bottom dynamically and with low computational cost
  • Ashok Kuvaraja
    Ashok Kuvaraja about 3 years
    You can add items to the data collection when it has reached the bottom like data.addAll([]). This time you just add the items to the collection instead of refreshing the whole list elements.
  • Admin
    Admin about 3 years
    Yes, but with future builder it will rebuild all the items when i add