#flutter #dart #flutter-provider
Вопрос:
Я использую FutureProvider для извлечения данных из локальной базы данных с помощью SQflite, а затем отображаю график в дочернем элементе потребителя. Однако при загрузке приложения в течение короткого периода времени отображается ошибка :
The following StateError was thrown building Consumer<List<Map<String, dynamic>>>(dirty,
dependencies: [_InheritedProviderScope<List<Map<String, dynamic>>>]):
Bad state: No element
После того, как график будет отрисован нормально.
Как я могу поймать это состояние загрузки, чтобы ошибка исчезла, и я мог показать CircularProgressIndicator() ?
Родитель
FutureProvider<List<Map<String, dynamic>>>(
create: (context) {
return RecordsDatabase.instance.getRecords();
},
catchError: (context, error) {
print("error: ${error.toString()}");
return [];
},
initialData: [],
child: HomeCustom(),
)
Ребенок
@override
Widget build(BuildContext context) {
return Consumer<List<Map<String, dynamic>>>(
builder: (context, records, child) {
GraphState graph =GraphState(records: records, context: context);
return ChangeNotifierProvider<GraphState>(
create: (_) => graph,
child: Scaffold(
backgroundColor: Colors.black,
body: Stack(children: [
Center(
child: graph.records.isEmpty
? Text(
'No Records',
style: TextStyle(color: Colors.white, fontSize: 24),
)
: MyGraph()),
Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: const EdgeInsets.only(right: 30, bottom: 50),
child: FloatingActionButton(
child: Icon(Icons.add),
onPressed: _setVisible,
),
),
)
]),
),
);
});
}
}
Ответ №1:
В поле Consumer
records
сначала проверьте значение , а затем верните соответствующий виджет.
Образец…
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: FutureProvider<List<Map<String, dynamic>>?>(
create: (_) => _getRecords(),
initialData: null,
catchError: (_, __) => <Map<String, dynamic>>[
{'error': 'Something went wrong'}
],
child: HomePage(),
),
);
}
Future<List<Map<String, dynamic>>> _getRecords() async {
final bool isError = false; // set to "true" to check error case
await Future<void>.delayed(const Duration(seconds: 5));
if (isError) {
throw Exception();
}
return <Map<String, dynamic>>[
<String, int>{'item': 1},
<String, String>{'itemTxt': 'one'},
];
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Consumer<List<Map<String, dynamic>>?>(
builder: (_, List<Map<String, dynamic>>? records, __) {
if (records == null) {
return const CircularProgressIndicator();
} else if (records.isNotEmpty amp;amp;
records.first.containsKey('error')) {
return Text(records.first['error'] as String);
}
return Text(records.toString());
},
),
),
);
}
}