After updating Dart and Flutter (3.5.2 and 3.24.2), PopScope stopped working and giving errors. In addition, result does not print a string. I looked at the documentation, but did not understand how to adjust the application to the new format.
The code itself should save the user's selected filters on a specific screen and save this information when switching to other screens.
Filters
import 'package:flutter/material.dart';
import 'package:food_catalog/screens/tabs.dart';
import 'package:food_catalog/widgets/main_drawer.dart';
enum Filter {
glutenFree,
lactoseFree,
vegetarian,
vegan,
}
class FiltersScreen extends StatefulWidget {
const FiltersScreen({
super.key,
required this.currentFilters,
});
final Map<Filter, bool> currentFilters;
@override
State<FiltersScreen> createState() => _FiltersScreenState();
}
class _FiltersScreenState extends State<FiltersScreen> {
var _glutenFreeFilterSet = false;
var _lactoseFreeFilterSet = false;
var _vegetarianFilterSet = false;
var _veganFilterSet = false;
@override
void initState() {
super.initState();
_glutenFreeFilterSet = widget.currentFilters[Filter.glutenFree]!;
_lactoseFreeFilterSet = widget.currentFilters[Filter.lactoseFree]!;
_vegetarianFilterSet = widget.currentFilters[Filter.vegetarian]!;
_veganFilterSet = widget.currentFilters[Filter.vegan]!;
}
void _saveFilters() {
Navigator.of(context).pop({
Filter.glutenFree: _glutenFreeFilterSet,
Filter.lactoseFree: _lactoseFreeFilterSet,
Filter.vegetarian: _vegetarianFilterSet,
Filter.vegan: _veganFilterSet,
});
}
@override
Widget build(BuildContext context) {
return PopScope(
onPopInvokedWithResult: (didPop) {
if (didPop) {
_saveFilters();
}
return false;
},
child: Scaffold(
appBar: AppBar(
title: const Text('Ваши фильтры'),
),
drawer: MainDrawer(onSelectScreen: (identifier) {
Navigator.of(context).pop();
if (identifier == 'meals') {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => const TabsScreen(),
),
);
}
}),
body: Column(
children: [
SwitchListTile(
value: _glutenFreeFilterSet,
onChanged: (newValue) {
setState(() {
_glutenFreeFilterSet = newValue;
});
},
title: Text(
'Не содержит глютена',
style: Theme.of(context).textTheme.titleLarge!.copyWith(
color: Colors.black,
),
),
subtitle: Text(
'Показать только блюда без глютена',
style: Theme.of(context).textTheme.labelMedium!.copyWith(
color: Colors.black54,
),
),
activeColor: Theme.of(context).colorScheme.tertiary,
contentPadding: const EdgeInsets.only(left: 34, right: 22),
),
SwitchListTile(
value: _lactoseFreeFilterSet,
onChanged: (newValue) {
setState(() {
_lactoseFreeFilterSet = newValue;
});
},
title: Text(
'Не содержит лактозу',
style: Theme.of(context).textTheme.titleLarge!.copyWith(
color: Colors.black,
),
),
subtitle: Text(
'Показать только блюда без лактозы',
style: Theme.of(context).textTheme.labelMedium!.copyWith(
color: Colors.black54,
),
),
activeColor: Theme.of(context).colorScheme.tertiary,
contentPadding: const EdgeInsets.only(left: 34, right: 22),
),
SwitchListTile(
value: _vegetarianFilterSet,
onChanged: (newValue) {
setState(() {
_vegetarianFilterSet = newValue;
});
},
title: Text(
'Только вегетарианские блюда',
style: Theme.of(context).textTheme.titleLarge!.copyWith(
color: Colors.black,
),
),
subtitle: Text(
'Показать только вегетарианские блюда',
style: Theme.of(context).textTheme.labelMedium!.copyWith(
color: Colors.black54,
),
),
activeColor: Theme.of(context).colorScheme.tertiary,
contentPadding: const EdgeInsets.only(left: 34, right: 22),
),
SwitchListTile(
value: _veganFilterSet,
onChanged: (newValue) {
setState(() {
_veganFilterSet = newValue;
});
},
title: Text(
'Только веганские блюда',
style: Theme.of(context).textTheme.titleLarge!.copyWith(
color: Colors.black,
),
),
subtitle: Text(
'Показать только веганские блюда',
style: Theme.of(context).textTheme.labelMedium!.copyWith(
color: Colors.black54,
),
),
activeColor: Theme.of(context).colorScheme.tertiary,
contentPadding: const EdgeInsets.only(left: 34, right: 22),
),
],
),
),
);
}
}
Tabs -----------------------------------------------------------------------------------------------------
import 'package:flutter/material.dart';
import 'package:food_catalog/data/dummy_data.dart';
import 'package:food_catalog/models/meal.dart';
import 'package:food_catalog/screens/category_view.dart';
import 'package:food_catalog/screens/filters.dart';
import 'package:food_catalog/screens/meals.dart';
import 'package:food_catalog/widgets/main_drawer.dart';
const kInitialFilters = {
Filter.glutenFree: false,
Filter.lactoseFree: false,
Filter.vegetarian: false,
Filter.vegan: false,
};
class TabsScreen extends StatefulWidget {
const TabsScreen({super.key});
@override
State<TabsScreen> createState() => _TabsScreenState();
}
class _TabsScreenState extends State<TabsScreen> {
int _selectedPageIndex = 0;
final List<Meal> _favoriteMeals = [];
Map<Filter, bool> _selectedFilters = kInitialFilters;
void _showInfoMessage(String message) {
ScaffoldMessenger.of(context).clearSnackBars();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
),
);
}
void _toggleMealFavoriteStatus(Meal meal) {
final isExisting = _favoriteMeals.contains(meal);
if (isExisting) {
setState(() {
_favoriteMeals.remove(meal);
});
_showInfoMessage('Чао персик, дозревай');
} else {
setState(() {
_favoriteMeals.add(meal);
_showInfoMessage('Опа чиназес, сюда!');
});
}
}
void _selectedPage(int index) {
setState(() {
_selectedPageIndex = index;
});
}
void _setScreen(String identifier) async {
Navigator.of(context).pop();
if (identifier == "Фильтры") {
final result = await Navigator.of(context).push<Map<Filter, bool>>(
MaterialPageRoute(
builder: (context) => FiltersScreen(
currentFilters: _selectedFilters,
),
),
);
setState(() {
_selectedFilters = result ?? kInitialFilters;
});
}
}
@override
Widget build(BuildContext context) {
final availableMeals = dummyMeals.where((meal) {
if (_selectedFilters[Filter.glutenFree]! && !meal.isGlutenFree) {
return false;
}
if (_selectedFilters[Filter.lactoseFree]! && !meal.isLactoseFree) {
return false;
}
if (_selectedFilters[Filter.vegetarian]! && !meal.isVegetarian) {
return false;
}
if (_selectedFilters[Filter.vegan]! && !meal.isVegan) {
return false;
}
return true;
}).toList();
Widget activePage = CategoriesScreen(
onToggleFavorite: _toggleMealFavoriteStatus,
availebleMeals: availableMeals,
);
var activePageTittle = 'Категории';
if (_selectedPageIndex == 1) {
activePage = MealsScreen(
meals: _favoriteMeals,
onToggleFavorite: _toggleMealFavoriteStatus,
);
activePageTittle = 'Избранное';
}
return Scaffold(
appBar: AppBar(
title: Text(activePageTittle),
),
drawer: MainDrawer(
onSelectScreen: _setScreen,
),
body: activePage,
bottomNavigationBar: BottomNavigationBar(
onTap: _selectedPage,
currentIndex: _selectedPageIndex,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.set_meal), label: "Категории"),
BottomNavigationBarItem(icon: Icon(Icons.stars), label: "Избранное"),
],
),
);
}
}
I tried to contact ChatGPT and Gemini but they couldn't solve the problem, although I asked them in different ways, for example, where could be the problem or find a typo in the code
PopInvokedWithResultCallback<dynamic>?
requires a callback function which accepts two parameters one for didPop
whether it's popped or not and the other for the returned result
.
Try the following:
PopScope(
onPopInvokedWithResult: (didPop, result) {
if (didPop) {
_saveFilters();
}
},