Flutter Listview.Builder внутри виджета нижнего листа не загружает данные при загрузке

Приведенный ниже код не отображает никаких данных при загрузке нижнего листа. После загрузки нижнего листа, если я выполняю операцию сохранения в редакторе кода, он загружает данные. Что мне здесь не хватает?

У меня есть виджет нижнего листа, который вызывается с помощью кнопки.

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

Приведенный выше код загружает виджет «Контакты», в котором есть Listview.builder, который показан ниже.

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),
                          ],
                        ),
                      );
                    },
                  ),
                ],
              ),
            ),
          );
        },
      ),
    );
  }
}

ты звонишь setState в loadContacts

Yeasin Sheikh 18.05.2022 04:49

@YeasinSheikh, я не был, я сделал, теперь все работает как положено. Спасибо Ясин. Не могли бы вы поставить это как ответ?

Sumchans 18.05.2022 04:51
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
0
2
18
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Поскольку функция initState() не ожидает вашего loadContacts(), данные загружаются после функции build().

Вам нужно использовать класс FutureBuilder для перестройки виджета ListView после загрузки данных.

Пример:

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}');                                           
                    }
                )
            );
         }
     }
)

Привет, Сайто, я загружаю данные в метод initstate виджета, который, как я думал, будет вызывать метод только после завершения выполнения метода.

Sumchans 18.05.2022 04:40

Я попробовал этот код: void initState() { pullContactsData(); супер.initState(); } void pullContactsData() async { await fetchSupabaseContactsAndCheckWithPhoneBookContacts(); }

Sumchans 18.05.2022 04:41

все еще не загружается

Sumchans 18.05.2022 04:41

если вы ожидаете всех функций loadContacts() следующим образом: «ожидайте loadContacts()», тогда основная функция вызывает метод после завершения выполнения метода. но initState() не может ждать, тогда вы должны использовать FutureBuilder

Saitoh Akira 18.05.2022 04:44

Вот почему я создал еще один метод только для ожидания, а затем вызывал этот метод из inistate(), как в приведенном выше фрагменте, который также не работает.

Sumchans 18.05.2022 04:45

Да но initState() не ждет вашего другого метода, который вы создали, вы можете распечатать все пошаговые методы, запущенные в вашей печати, вы увидите

Saitoh Akira 18.05.2022 04:47

Хорошо, спасибо Сайто

Sumchans 18.05.2022 04:49
Ответ принят как подходящий

Я не предпочитаю использовать FutureBuilder внутри StatefulWidget, он будет вызывать API(future) для каждого setState. Что касается комментария, то он отсутствует setState после инициализации данных.

  @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
  }

Другие вопросы по теме