I am trying to update a GridView.builder with setState and when the change is triggered, the actual state is updated behind the scene but the GridView.builder does not change until I manually refresh the app.
The setState function triggers and I have tested this. Here is the code:
import 'package:flutter/material.dart';
import 'image_display_card.dart';
void main() {
runApp(MaterialApp(
home: ChooseScreen(),
));
}
class ChooseScreen extends StatefulWidget {
@override
State<ChooseScreen> createState() => _ChooseScreenState();
}
class _ChooseScreenState extends State<ChooseScreen> {
DisplayCard? currentSelectedCard;
// The List of image cards
List<DisplayCard> baseDisplayList = [];
// These are dummy images I added
List<Image> listOfInitialImages = const [
Image(image: AssetImage('images/testing_stock/stickFigureMale.png')),
Image(image: AssetImage('images/testing_stock/stickFigureFemale.png')),
Image(image: AssetImage('images/testing_stock/gown.png')),
Image(image: AssetImage('images/testing_stock/hat1.png')),
];
@override
void initState() {
super.initState();
baseDisplayList = [
for (int i = 0; i < listOfInitialImages.length; i++)
DisplayCard(
picture: listOfInitialImages[i],
onCardSelected: () {
setCardToSelected(i);
},
),
];
}
/// unselect the previous selected card and
/// set currentSelectedCard to the new selected card.
setCardToSelected(int index) {
if (currentSelectedCard != null) {
currentSelectedCard!.selectOrUnselect(false);
}
print('triggered');
// set the new selected card.
currentSelectedCard = baseDisplayList[index];
currentSelectedCard!.selectOrUnselect(true);
print('triggered again');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Choose picture'),
),
body: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: baseDisplayList.length,
itemBuilder: (BuildContext context, int index) {
return baseDisplayList[index];
},
),
);
}
}
And this is display_card.dart
:
import 'package:flutter/material.dart';
class DisplayCard extends StatelessWidget {
final Image picture;
final onCardSelected;
bool isSelected;
// TODO: Implement color change on selected picture
DisplayCard({
this.isSelected = false,
this.onCardSelected,
this.picture = const Image(
image: AssetImage('images/testing_stock/stickFigureMale.png')),
});
selectOrUnselect(bool choice) {
isSelected = choice;
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onCardSelected,
child: Container(
height: 200,
margin: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.grey[300],
image: DecorationImage(
image: picture.image,
colorFilter: ColorFilter.mode(
Colors.black.withOpacity(isSelected ? 0.4 : 0.0),
BlendMode.srcOver
),
fit: BoxFit.cover,
),
),
),
);
}
}
I've edited it to contain only the necessary code to replicate the error. Sorry for before.
The state of baseDisplayList is updated but the GridView.builder is not rebuilt.
Ragarding how I know the GridView.builder
isn't rebuilt, I tried changing the backgroundColor of the scaffold in the setCardToSelected
function and the background color changed but the GridView didn't change. But when I refresh the app immediately afterwards, the GridView updated.
Please, how can I make the GridView.builder
update when the setCardToSelected
is called?
Thank you. I appreciate your help.