I wanted to have a text, that changes every time one of the filter cards is selected/deselected. I made a global variable (I don't know what the best way to do that is but to me it seemed like it should work) and changed the value of it every time one of the filter cards was tapped. The problem is that the text widget, where the value is supposed to be displayed, doesn't change although the output shows, that the set state function worked. For more info see the pictures and code below.
class FilterSelectCard extends StatefulWidget {
FilterSelectCard({
Key? key,
required this.filterCategory,
required this.filterSvg,
required this.filterIndex,
required this.appliedFilters,
}) : super(key: key);
List<String> filterCategory;
List<String> filterSvg;
int filterIndex;
ValueNotifier<int> appliedFilters;
@override
FilterSelectCardState createState() => FilterSelectCardState();
}
class FilterSelectCardState extends State<FilterSelectCard> {
Color filterColor = primaryColor;
Color borderColor = secondaryTextColor;
Color svgColor = secondaryTextColor;
bool filterStat = false;
TextStyle textStyle = unTextStyle;
ValueNotifier<int> appliedFilters = widget.appliedFilters;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(
right: 12,
),
child: GestureDetector(
onTap: () {
setState(() {
if (filterStat == false) {
filterColor = secondaryTextColor;
textStyle = selTextStyle;
borderColor = backgroundColor;
svgColor = mainTextColor;
appliedFilters.value += 1;
print(appliedFilters);
}
if (filterStat == true) {
filterColor = primaryColor;
textStyle = unTextStyle;
borderColor = secondaryTextColor;
svgColor = secondaryTextColor;
appliedFilters.value -= 1;
print(appliedFilters);
}
if (filterColor == primaryColor) {
filterStat = false;
}
if (filterColor == secondaryTextColor) {
filterStat = true;
}
});
},
and
Future<dynamic> filterMealsAndWines(BuildContext context) {
ValueNotifier<int> appliedFilters = ValueNotifier(0);
return showModalBottomSheet(
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(35),
),
builder: (BuildContext context) {
return Stack(
children:[Positioned(
left: 110,
top: 15,
child: Container(
height: 9,
width: 20,
decoration: BoxDecoration(
color: primaryColor,
borderRadius: BorderRadius.circular(
20,
),
),
child: ValueListenableBuilder(
valueListenable: appliedFilters,
builder: (context, appliedFilters, _) {
return Center(
child: Text(
appliedFilters.toString(),
style: GoogleFonts.poppins(
textStyle: const TextStyle(
color: mainTextColor,
fontSize: 6,
fontWeight: FontWeight.w600,
),
),
),
);
},
),
),
),],
If this widget, is the widget you are trying to update when setState() is called, it doesn't work because it is not in same StatefulWidget as the setState() function in result the widget doesn't rebuild.
child: Center(
child: Text(
appliedFilters.toString(),
style: GoogleFonts.poppins(
textStyle: const TextStyle(
color: mainTextColor,
fontSize: 6,
fontWeight: FontWeight.w600,
),
),
),
),
To solve you should read more about state managment in Flutter, but a temporary solution could be using a ValueListenableBuilder
So you should wrap your Text widget in ValueListenableBuilder and your your value appliedFilters will update the builder whenever it is changed
Future<dynamic> filterMealsAndWines(BuildContext context){
ValueNotifier<int> appliedFilters = ValueNotifier(0);
//Your all previuos code
ValueListenableBuilder<int>(
valueListenable: appliedFilters,
builder: (context, value, _) {
return Center(
child: Text(
appliedFilters.toString(),
style: GoogleFonts.poppins(
textStyle: const TextStyle(
color: mainTextColor,
fontSize: 6,
fontWeight: FontWeight.w600,
),
),
),
);
}
),
}
class FilterSelectCardState extends State<FilterSelectCard> {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(
right: 12,
),
child: GestureDetector(
onTap: () {
setState(() {
//HERE YOU UPDATE THE VALUE
widget.appliedFilters.value += 1;
});
},
),
//all your other code
);
}
}