I have a Flutter app where setState() function is called inside loadExpenses() function right after a database query method. initially the count of the expense list (expCount) is set to 0. Later on, based on the selection of fund, the expense list is updated and hence the expCount is updated so that ListView.builder() can properly update the listview. However, I can observe that after selecting fund from fund dropDownMenu the expenseList is updated properly in the loadExpenses() function. But this.expCount = _expenses.length; is not updating the expCount value and that's why the ListView Builder cannot create the list.
this.dbHelper
.getExpensesByFundId(this._selectedFund.id)
.then((List<Expense> expenses) {
setState(() {
this._expenses = expenses;
this.expCount = _expenses.length;
});
However, if I take that line outside the setState() function, I can see the expCount variable is updating just find. Can you tell me what is the problem here?
Here is my code:
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,
),
);
}
}