Flutter : update specific item in a ListView
I have a list a user object they hold a user data and displays as ListView. Each item has one button, when I click on an item button I'm trying to update particular item in ListView. But i can't and I was reloaded the full ListView like below... . I want In a sequence updating only a particular object in my list data and update these button title and change colour purple into green based on payment id. Is there anyway to only update an item in a ListView without having to refresh the entire list?
ListView which is loaded like this:
FutureBuilder(
future: getInwardResidentList(param),
builder: (BuildContext context, AsyncSnapshot snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:{
return Container();}
case ConnectionState.active:{
break;}
case ConnectionState.done:{
if (snapshot.hasData) {
if (snapshot.data != null) {
if (snapshot.data.length > 0) {
return Container(
color: Colors.white70,
child: Scrollbar(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
physics: ScrollPhysics(),
padding: EdgeInsets.all(5),
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return generateColumn(item, index)
}),
),
);
}
}
}
}
}
return Container();
},
)
Here is my on click button code
Widget generateColumn(InwardResidentModel item, int index) => Column(
children: <Widget>[
Row(
children: <Widget>[
...,
...,
Column(
children: <Widget>[
if (item.payment_status_id == "1")
MaterialButton(
onPressed: () {},
minWidth: 50,
height: 25,
padding: EdgeInsets.all(8),
child: Text("Paid ₹${item.amount}",
style: TextStyle(
color: Colors.green, fontSize: 13)),
),
if (item.payment_status_id != "1")
MaterialButton(
onPressed: () {
setState(() {
inwardResidentModelList[index] = InwardResidentModel.fromJson({'payment_status_id': "1"});
// inwardResidentModelList[inwardResidentModelList.indexWhere((element) => item.inward_user_id == item.inward_user_id)] = InwardResidentModel(payment_status_id: "1");
});
},
minWidth: 50,
height: 25,
padding: EdgeInsets.all(8),
child: Text("Pay ₹${item.payable_amount}",
style: TextStyle(
color: Colors.deepPurple, fontSize: 13)),
)
],
)
],
),
],
);
User model class look like
class InwardUserModel {
final String inward_user_id;
final String user_id;
final String payment_status_id;
final String first_name;
final String middle_name;
final String last_name;
final String amount;
InwardUserModel({
this.inward_user_id,
this.user_id,
this.payment_status_id,
this.first_name,
this.middle_name,
this.last_name,
this.amount,
});
factory InwardUserModel.fromJson(Map<String, dynamic> parsedJson) {
return InwardUserModel(
user_id: parsedJson['user_id'] ?? "",
payment_status_id: parsedJson['payment_status_id'] ?? "",
first_name: parsedJson['first_name'] ?? "",
middle_name: parsedJson['middle_name'] ?? "",
last_name: parsedJson['last_name'] ?? "",
amount: parsedJson["amount"] ?? "",
);
}
}
How can I update each item separately to display the new title and change colour correctly by clicking on it without reloading full ListView? Any help is appreciated.
Solution 1:
If you keep generateColumn(item, index) your click button code in the same stateful widget of your List everytime you will call setState it will build the entire page from head to toe.
A simple solution could be to make a stateful Widget out of the click button, so to isolate it and better manage the state inside