I have a FutureBuilder that returns a ListViewBuilder in a class.
When loading the class the FutureBuilder loads the future which is a call to a API, then the ListView shows the received items inside Cards.
It is working fine, at this moment there are three items that should and are showed.
Then I am trying to verify if the class is updated when executing setState at a button click action. I am manually adding or removing items from the database that is called from the API, but clicking on the refres button after adding/removing items from the database, the list is not changing.
Here you have the code:
Container(
height: 120,
child:
FutureBuilder(
future: fetchFotosInformesIncidenciasTodos(
widget.informeActual.codigo),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<dynamic>? filteredList =
snapshot.data as List?;
filteredList ??= [];
listaFotosInformeIncidenciasActual =
filteredList;
WidgetsBinding.instance
.addPostFrameCallback((t) {
setState(() {
numeroFotosSubidas =
filteredList!.length
numeroFotosSubidasAhora;
});
});
return ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: filteredList.length,
shrinkWrap: false,
itemBuilder: (BuildContext context, index) {
FotoInformeIncidenciasModelo foto =
filteredList![index];
var urlFoto = Constantes
.adminInformesIncidenciasUrl
foto.archivo;
return GestureDetector(
onTap: () {
print("pulsada foto ${foto.id}");
},
child: Card(
elevation: 6,
child: (Column(
children: [
Image.network(
urlFoto,
width: 60,
height: 80,
),
],
)),
));
},
);
}
return Image.asset(
"imagenes/vacio.png",
fit: BoxFit.contain,
);
},
),
),
And here the refresh button:
InkWell(
onTap: (){
setState(() {
print("refrescando");
});
},
child: Text("refrescar")),
I would like to know why is the call to setState not forcing to update the FutureBuilder and the ListView Builder
CodePudding user response:
The future function fetchFotosInformesIncidenciasTodos(widget.informeActual.codigo) which is being called directly from the Future block. You need to make an instance of the future and invoke the same whenever you want a new request for the future eg.
Future<Response> _futureFun;
....
@override
void initState() {
super.initState();
_futureFun =
fetchFotosInformesIncidenciasTodos(widget.informeActual.codigo)
}
_futureFun = fetchFotosInformesIncidenciasTodos(widget.informeActual.codigo){}
@override
Widget build(BuildContext context) {
....
FutureBuilder<Response>(
future: _futureFun,
....
}
And to refresh the data again, just call the function fetchFotosInformesIncidenciasTodos(widget.informeActual.codigo) again and there is not need to setState.