Как загрузить данные начального состояния из базы данных 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 не может быть асинхронным, потому что он должен запускаться перед вашим основным приложением, чтобы мы могли использовать для него внешнюю функцию.

  1. Определите функцию с именем sqlData() с помощью asyncawait
  2. Назовите это внутри 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");    
      } 
  },)
Другие вопросы по тегам