Flutter: функция setState() неправильно обновляет значение
У меня есть приложение Flutter, где функция setState() вызывается внутри функции loadExpenses() сразу после метода запроса к базе данных. изначально счет списка расходов (expCount) устанавливается равным 0. Позже, в зависимости от выбора фонда, список расходов обновляется, и, следовательно, expCount обновляется, чтобы ListView.builder () мог правильно обновить представление списка. Тем не менее, я могу заметить, что после выбора фонда из фонда dropDownMenu расходный список корректно обновляется в функции loadExpenses(). Но this.expCount = _expenses.length; не обновляет значение expCount, и поэтому ListView Builder не может создать список.
this.dbHelper.getExpensesByFundId (this._selectedFund.id).then ((список расходов) { setState(() { this._expenses = расходы; this.expCount = _expenses.length;
});
Однако, если я возьму эту строку за пределы функции setState(), я увижу, что переменная expCount обновляется просто find. Можете ли вы сказать мне, в чем здесь проблема?
Вот мой код:
import 'package:flutter/material.dart';
import 'package:ksk_tavel_exp/Models/expense.dart';
import 'package:ksk_tavel_exp/Models/fund.dart';
import 'package:ksk_tavel_exp/utils/dbHelper.dart';
class ExpenseList extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return ExpenseListState();
}
}
class ExpenseListState extends State<ExpenseList> {
List<Fund> _funds;
List<Expense> _expenses;
Fund _selectedFund;
int expCount = 0;
DatabaseHelper dbHelper = DatabaseHelper();
loadFunds() {
if (this._selectedFund == null) {
this.dbHelper.getFunds().then((List<Fund> funds) {
setState(() {
this._funds = funds;
this._selectedFund = this._funds[0];
this.loadExpenses();
});
});
}
}
loadExpenses() {
this
.dbHelper
.getExpensesByFundId(this._selectedFund.id)
.then((List<Expense> expenses) {
setState(() {
this._expenses = expenses;
this.expCount = _expenses.length;
});
});
}
Widget expenseBuilder(BuildContext context, int index) {
return ListTile(
leading: Text(this._expenses[index].date),
title: Text(this._expenses[index].expense),
trailing: Text('${this._expenses[index].amount} BDT'),
);
}
@override
Widget build(BuildContext context) {
double screenHeight = MediaQuery.of(context).size.height;
this.loadFunds();
// this.loadExpenses();
return Scaffold(
appBar: AppBar(
title: Text('KSK Expense App'),
elevation: 1.0,
),
body: Column(
children: <Widget>[
this._funds != null && this._selectedFund != null
? getFunds(screenHeight)
: Container(),
this._expenses != null ? this.getExpenses(screenHeight) : Container()
],
),
);
}
Container getFunds(double screenHeight) {
return Container(
height: screenHeight*0.05,
child: ListTile(
leading: Text('Fund'),
title: DropdownButton<Fund>(
items: _funds.map((Fund item) {
return DropdownMenuItem<Fund>(
value: item,
child: Text(item == null ? '' : item.fundName),
);
}).toList(),
onChanged: (Fund selectedFund) {
this._selectedFund = selectedFund;
this.loadExpenses();
this.expCount = _expenses.length;
},
),
),
);
}
Widget getExpenses(double screenHeight) {
return Container(
height: screenHeight*0.80,
child: ListView.builder(
itemBuilder: this.expenseBuilder,
itemCount: this.expCount,
),
);
}
}
1 ответ
Нет необходимости включать
this.expCount = _expenses.length;
внутри
setState()
, его можно использовать на
ListView.builder()
непосредственно, поскольку виджеты будут перестроены после вызова setState().
ListView.builder(
itemBuilder: this.expenseBuilder,
itemCount: _expenses.length,
),
Я также нахожу странным видеть необходимость обновления
expCount
после звонка
loadExpenses()
внутри
DropdownButton.onChanged()