Как загрузить данные начального состояния из базы данных sqlite при открытии приложения Flutter
Я делаю простое приложение "Блокнот", используя флаттер. Я хочу загрузить уже сохраненные данные из базы данных SQLite и инициализировать состояние при открытии приложения. Я пробовал использовать метод initState() с методом async. Но асинхронные методы не работают в методе initState(). В некоторых местах говорят об использовании Future Builder и BLoC. Но я не совсем уверен, что хорошо. Как лучше всего это реализовать во флаттере??
4 ответа
У вас есть два варианта.
Вариант 1. Делайте то, что говорит @UtakarshSharma. Пример реализации ниже.
@override
void initState() {
super.initState();
_requestSqlData();
}
void _requestSqlData(){
_requestSqlDataAsync();
}
void _requestSqlData() async {
var _data = await getData(); // call API/await function to get the data
}
Вариант 2. Используйте метод обратного вызова после полноэкранной загрузки. И используйте setState для обновления экрана. Вам нужно будет использовать flutter_after_layout (https://github.com/slightfoot/flutter_after_layout). Он выполняет функцию после завершения макета.:
void initState() {
super.initState();
WidgetsBinding.instance
.addPostFrameCallback((_) => myAwesomeFunction(context));
}
Я нашел, что этот подход работает для меня. используйте.then() в своей асинхронной функции
@override
void initState() {
super.initState();
db.getData().then((value){
_valueState = value;
});
}
Если вы знаете, как загружать данные из sql lite, определите эту функцию вне initstate(), используя async и await, и вызовите ее в initstate() . Initstate не может быть асинхронным, потому что он должен запускаться перед вашим основным приложением, чтобы мы могли использовать для него внешнюю функцию.
- Определите функцию с именем sqlData() с помощью asyncawait
- Назовите это внутри initstate.
Фьючерсы — лучший способ обработки выборки данных и их отображения в пользовательском виджете.
late Future<YourDataType> dataItems;
@override
void initState(){
super.initState();
dataItems = getData();
}
Вы также можете добавить try-catch внутри этого метода.
Future<YourDataType> getData() async{
return await yourEndPointToFetchData();
}
Внутри строителя используйте FutureBuilder, как это
FutureBuilder<YourDataType>(
future: dataItems,
builder: (context, snapshot) {
switch (snapshot.connectionState){
case ConnectionState.none:
return const Center(child: Text("your message"));
case ConnectionState.active:
case ConnectionState.waiting:
return const Center(child: CircularProgressIndicator());
case ConnectionState.done:
if(snapshot.data == null || snapshot.data.items.isEmpty){
return const Center(child: Text("no data"),);
}
return yourWidget(snapshot.data.items);
default:
return const Text("Your message");
}
},)