I am new to flutter and trying to do my first assignment. I have been looking all over but can't find why PopupMenuButoon doesn't work. I use it to switch between all items and favorites only but it only changes the values and does not rerender the screen. Here is a snippet of my code.
enum FilterOptions {
Favorites,
All,
}
...
@override
Widget build(BuildContext context) {
bool _showOnlyFavorites = false;
return Scaffold(
appBar: AppBar(
actions: [
PopupMenuButton(
itemBuilder: (_) => [
PopupMenuItem(
child: Text('Only Favorites'),
value: FilterOptions.Favorites,
),
PopupMenuItem(
child: Text('Show All'),
value: FilterOptions.All,
),
],
onSelected: (FilterOptions selectedValue) {
setState(() {
if (selectedValue == FilterOptions.Favorites) {
setState(() {
_showOnlyFavorites = true;
});
} else {
setState(() {
_showOnlyFavorites = false;
});
}
});
},
),
],
...
),
body: RecipesGrid(_showOnlyFavorites),
class RecipesGrid extends StatelessWidget {
bool isFav;
RecipesGrid(this.isFav);
@override
Widget build(BuildContext context) {
final recipeData = Provider.of<RecipeProvider>(context);
List<Recipe> recipes = isFav == false ? recipeData.recipes : recipeData.favoritesList;
return GridView.builder(
itemCount: recipes.length,
padding: EdgeInsets.all(10),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
mainAxisSpacing: 10,
crossAxisSpacing: 5,
childAspectRatio: 2.3 / 1,
),
itemBuilder: (context, i) => ChangeNotifierProvider.value(
value: recipes[i],
child: isFav == true && recipes == []
? Text('You don\'t have any favorites yet. Start adding some!')
: RecipeItem(),
),
);
}
}
CodePudding user response:
bool _showOnlyFavorites = false;
This variable is local to your build method. That means it is thrown away and reinstated with it's assigned value every time the build function is called. For obvious reasons, having state changes saved in a variable that resets every time the state changes is not going to work.
You need to put this variable somewhere else. If this is a state class, you could put it on class level, otherwise you need some state management approach. You already seem to have a provider, so you know how it works.
CodePudding user response:
Don't use setState in Nested way. Just follow the code given below:
if (selectedValue == FilterOptions.Favorites) {
setState(() {
_showOnlyFavorites = true;
});
} else {
setState(() {
_showOnlyFavorites = false;
});
}
