Я хочу построить карты на основе данных, полученных из будущего, которое возвращает карту. Поскольку 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);
}
}