Как ожидать, что itemCount в ListView в флаттере Future Builder? - PullRequest
0 голосов
/ 08 апреля 2020

Я хочу построить карты на основе данных, полученных из будущего, которое возвращает карту. Поскольку cardDetails извлекается из бэкэнда, требуется некоторое время, но при сборке карт с использованием ListView.builder он достигает itemCount, прежде чем данные извлекаются, что делает cardDetails равным null. Если я жестко закодирую значение itemCount, ошибка исчезнет, ​​и я получу карточки по мере необходимости. Любые подсказки о том, как решить эту проблему, были бы полезны.

Обновление: оно входит в состояние snapshot.hasError, но я не могу выяснить, какая это ошибка

В пользовательском интерфейсе

 if (_localStorageService.getStringFromLocalStorage() != 'testFalse')
              FutureBuilder(
                future: _localStorageService.getMapFromLocalStorage(),
                builder: (BuildContext context, AsyncSnapshot snapshot) {
                  if (snapshot.hasData) {
                    cardDetails = snapshot.data;
                    return ListView.builder(
                      itemBuilder: (context, index) {
                        print("Shared Pref hasData");
                        return cardDetails == null
                            ? CircularProgressIndicator()
                            : HomepageCards(
                                user: widget.user,
                                cardDetails: cardDetails[
                                    cardDetails.keys.toList()[index]],
                              );
                      },
                      // verify if cardDetails is null to prevent app crash
                      itemCount:
                          (cardDetails == null ? 0 : cardDetails.keys.length),
                      scrollDirection: Axis.vertical,
                      controller: _controller,
                      shrinkWrap: true,
                    );
                  } else if (snapshot.hasError) {
//                    TODO: Shimmer skeleton
                  }
                  return CircularProgressIndicator();
                },
              )
            else
              StreamBuilder<DocumentSnapshot>(
                stream: Firestore()
                    .collection('homepage')
                    .document(widget.user.uid)
                    .collection('h')
                    .document('28032020')
                    .snapshots(),
                builder: (context, snapshot) {
                  if (snapshot.data != null) {
                    cardDetails = {};
                    snapshot.data.data.forEach((index, individualDetail) {
                      cardDetails[index] = individualDetail;
                    });
                    _localStorageService
                        .storeCardInSharedPreference(cardDetails);
                    cardDetailKeys = snapshot.data.data.keys;
                  } else if (snapshot.hasError) {
//                    TODO: Show skeletal shimmer
                  } else {
                    // TODO: Convert it to Shimmer with card skeletal layout
                    CircularProgressIndicator();
                  }
                  return cardDetails == null
                      ? CircularProgressIndicator()
                      : ListView.builder(
                          itemBuilder: (context, index) {
                            return HomepageCards(
                              user: widget.user,
                              cardDetails:
                                  cardDetails[cardDetails.keys.toList()[index]],
                            );
                          },
                          itemCount: (cardDetailKeys == null
                              ? 0
                              : cardDetailKeys.length),
                          scrollDirection: Axis.vertical,
                          controller: _controller,
                          shrinkWrap: true,
                        );
                },
              )

Сервис LocalStorage для общих настроек

class LocalStorageService {
  static SharedPreferences _sharedPreferences;
  final String screenkey;
  String value;
  String _initialSharedValue;

  LocalStorageService({@required this.screenkey});

  initialiseLocalStorage() async {
    _sharedPreferences = await SharedPreferences.getInstance();
    persist(screenkey);
  }

  Future<void> persist(String key) async {
    _initialSharedValue = _sharedPreferences?.getString(key);
    // will be null if never previously saved
    if (_initialSharedValue == null) {
      _initialSharedValue = 'testFalse';
    }
    await _sharedPreferences?.setString(screenkey, _initialSharedValue);
    print("share = ${_sharedPreferences?.getString(screenkey)}");
  }

  storeCardInSharedPreference(Map cardDetails) async {
    await _sharedPreferences?.setString(screenkey, json.encode(cardDetails));
  }

  getMapFromLocalStorage() async {
    return await json.decode(_sharedPreferences?.getString(screenkey));
  }

  String getStringFromLocalStorage() {
    return _sharedPreferences?.getString(screenkey);
  }
}

1 Ответ

1 голос
/ 08 апреля 2020

Это потому, что независимо от статуса вашего будущего строителя, Listview возвращается. Если вы хотите контролировать статус вашего будущего строителя, вы должны поместить возврат в ваш if / else / case.

Таким образом:

FutureBuilder(
            future: _localStorageService.getStringFromLocalStorage(),
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              if (snapshot.hasData) {
                cardDetails = snapshot.data;
                print("number of cards = ${cardDetails.keys.length}");
                return ListView.builder(
                itemBuilder: (context, index) {
                  print("card details in futute : ${snapshot.data}");
                  return cardDetails == null
                      ? CircularProgressIndicator()
                      : HomepageCards(
                          user: widget.user,
                          cardDetails:
                              cardDetails[cardDetails.keys.toList()[index]],
                        );
                },
                // verify if cardDetails is null to prevent app crash
                itemCount: (cardDetails == null? 0: cardDetails.keys.length),
                scrollDirection: Axis.vertical,
                controller: _controller,
                shrinkWrap: true,
              );
              } else if (snapshot.hasError) {
                print("Error here in snapshot");
                return Center(child:Text("An error has occurred"));
              } else {
                return CircularProgressIndicator();
              }

            },
          )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...