#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.
ошибка выдаст @racr0x2. итак, я искал ошибку, которую я получил, затем я нахожу
WidgetsBinding.instance.addPostFrameCallback((_){});
с этим я могу использовать setState с в виджете, но когда я использую это, это увеличивает цену без ограничения, @racr0x3. Я думал, что этого не произойдет, но не тестировал. Я обновлю с помощью надлежащего решения.
4. брат, я понял, но это не совсем так, как я думаю, эта страница содержит два виджета, поэтому я объединил второй виджет с первым виджетом с помощью future builder, теперь это работает, я думаю, это не очень хороший способ @racr0x
5. Есть много способов сделать то, что вы хотите: использовать потоки (см. Шаблон блоков), поставщика, унаследованные виджеты, все они управляют состояниями и обновляют дерево виджетов. Использование FutureBuilder с большими деревьями виджетов внутри — не лучший вариант, но с меньшими деревьями проблем нет.