Данные, не обновляющиеся для другого виджета flutter

#flutter

#сбой

Вопрос:

Я пытаюсь показать цену товаров в корзине, но общая стоимость должна быть указана в текстовом поле. Я сохраняю данные в SQLite и извлекаю их, а затем показываю виджету, но когда я пытаюсь получить доступ total_price к другому виджету, он не обновляется, но когда я снова нажимаю горячую перезагрузку, данные отображаются, но не в первый раз, когда я открываю страницу

   return FutureBuilder<List<CartModel>>(
      future: fetchCartFromDatabase(),
      builder: (context, snapshot) {

        if (snapshot.hasData amp;amp; snapshot.data.length > 0) {
           cartCount = snapshot.data.length;
           for(int i = 0;i<snapshot.data.length;i  ){
            var price = snapshot.data[i].product_price.split("₹");
            total_price =double.parse(price[1]);
          }
  } else if (snapshot.hasData amp;amp; snapshot.data.length == 0) {
          return new Text("No Data found");
        }
        else
          {
            return new Container(
              alignment: AlignmentDirectional.center,
              child: new CircularProgressIndicator(),
            );
          }
);
  

инициализировано значение

   int cartCount = 0;
  double total_price=0.0;
  

Ответ №1:

FutureBuilder Обновляет только своих дочерних элементов. Чтобы обновить значение другого виджета, вы должны использовать setState .

Лучшим способом было бы перевести FutureBuilder на верхний уровень или использовать какой-нибудь менеджер состояний, например provider.

Чтобы использовать setState, вам необходимо инициализировать выборку из initState stetefullWidget (или вызвать его из функции). Таким образом, вам не понадобится FutureBuilder, и вам придется рефакторинговать свой код:

 class YourWidget extends StatefulWidget {
  @override
  _YourWidgetState createState() => _YourWidgetState();
}

class _YourWidgetState extends State<YourWidget> {
  double total_price = 0;

  @override
  void initState() {
    super.initState();
    fetchCartFromDatabase().then((value){
      setState((){
        for(int i = 0;i<value.length;i  ){
          var price = value[i].product_price.split("₹");
          total_price =double.parse(price[1]);
        } 
      });
    });
  }
}
  

Обратный вызов addPostFrameCallback не является хорошим решением, поскольку он обновляет значение только в следующем кадре. Когда приложение растет, это приводит к задержкам.

Чтобы продолжить использование FutureBuilder, переместите дерево виджетов, которое необходимо обновить, внутрь FutureBuilder.

Комментарии:

1. setState не работает, я пробовал, при использовании seState внутри виджета эта setState() or markNeedsBuild() called during build. ошибка выдаст @racr0x

2. итак, я искал ошибку, которую я получил, затем я нахожу WidgetsBinding.instance.addPostFrameCallback((_){}); с этим я могу использовать setState с в виджете, но когда я использую это, это увеличивает цену без ограничения, @racr0x

3. Я думал, что этого не произойдет, но не тестировал. Я обновлю с помощью надлежащего решения.

4. брат, я понял, но это не совсем так, как я думаю, эта страница содержит два виджета, поэтому я объединил второй виджет с первым виджетом с помощью future builder, теперь это работает, я думаю, это не очень хороший способ @racr0x

5. Есть много способов сделать то, что вы хотите: использовать потоки (см. Шаблон блоков), поставщика, унаследованные виджеты, все они управляют состояниями и обновляют дерево виджетов. Использование FutureBuilder с большими деревьями виджетов внутри — не лучший вариант, но с меньшими деревьями проблем нет.