Home > Net >  Flutter Listview.Builder inside bottom sheet widget not loading data on load
Flutter Listview.Builder inside bottom sheet widget not loading data on load

Time:05-18

The below code does not display any data when the bottomsheet loads. Once the bottomsheet is loaded if I do a save operation on the code editor it loads the data. What am I missing here?

I have a bottomsheet widget which is invoked using a button.

_showBottomSheet() {
    showModalBottomSheet(
      context: context,
      builder: (context) {
        return const Contacts();
      },
    );
  }

The above code loads up the Contacts widget that has a Listview.builder in it which is below.

class Contacts extends StatefulWidget {
  const Contacts({Key? key}) : super(key: key);

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

class _ContactsState extends State<Contacts> {
  List<PhoneBookContact> phoneBookContacts1 = [];
  List<PhoneBookContact> phoneBookContacts2 = [];
  
  @override
  void initState() {
    loadContacts();
    super.initState();
  }

  Future loadContacts() async {
    ///somecode to gather data for the listview builder
    ///populates the phoneBookContacts1 & phoneBookContacts2 lists
  }


  @override
  Widget build(BuildContext context) {
    return Column(children: [
      const Text('Contacts Set 1'),
      displayPhoneBookContacts(phoneBookContacts1),
      const Text('Contacts Set 2'),
      displayPhoneBookContacts(phoneBookContacts2),
    ]);
  }

  Widget displayPhoneBookContacts(phoneBookContacts) {
    return Expanded(
      child: ListView.builder(
        shrinkWrap: true,
        itemCount: phoneBookContacts.length,
        itemBuilder: (BuildContext context, int index) {
          return Card(
            margin: const EdgeInsets.all(10),
            child: ListTile(
              contentPadding: const EdgeInsets.all(10),
              title: Column(
                children: [
                  Text(phoneBookContacts[index].phoneBookContact.toString()),
                  const SizedBox(
                    height: 20,
                  ),
                  ListView.separated(
                    physics: const ClampingScrollPhysics(),
                    shrinkWrap: true,
                    itemCount: phoneBookContacts[index].contactNumbers!.length,
                    separatorBuilder: (BuildContext context, int index) =>
                        const Divider(),
                    itemBuilder: (BuildContext context, int phoneIndex) {
                      return InkWell(
                        onTap: () {},
                        child: Row(
                          children: [
                            Text(phoneBookContacts[index]
                                .contactNumbers![phoneIndex]
                                .phone),
                          ],
                        ),
                      );
                    },
                  ),
                ],
              ),
            ),
          );
        },
      ),
    );
  }
}

CodePudding user response:

I don't prefer using FutureBuilder inside StatefulWidget., it will recall the API(future) on every setState. As for comment it is missing setState after initializing the data.

  @override
  void initState() {
    super.initState();
    loadContacts();
  }

  Future loadContacts() async {
    ///somecode to gather data for the listview builder
    ///populates the phoneBookContacts1 & phoneBookContacts2

    setState(() {});// make sure to call setState
  }

CodePudding user response:

Because function initState() don't await your loadContacts(), data loaded after function build().

You need use FutureBuilder class to rebuild ListView widget after load data

Example:

FutureBuilder(
    future: loadContacts(),
    builder:(context, AsyncSnapshot snapshot) {
        if (!snapshot.hasData) {
            return Center(child: CircularProgressIndicator());
         } else {
            return Container(
                child: ListView.builder(                                                  
                    itemCount: _faouriteList.length,
                    scrollDirection: Axis.horizontal,
                    itemBuilder: (BuildContext context, int index) {
                        return Text('${_faouriteList[index].title}');                                           
                    }
                )
            );
         }
     }
)
  • Related