Menu
CoddyTech

Livre de recettes : Onglet Favoris

Fait partie de la section Listes et écrans du Journey Flutter de Coddy. Leçon 32 sur 33.

Les cœurs ne sont utiles que si tu peux retrouver tes favoris. Un deuxième onglet, Favorites, affiche uniquement les recettes avec un cœur rouge.

Les deux onglets affichent une liste de recettes qui se ressemble ; écris donc la liste une seule fois, sous la forme d’une méthode qui prend les recettes à afficher :

Widget recipeList(List<Recipe> shown) {
  return ListView.builder(...);
}

Les favoris sont les recettes where favorite est true. Détermine-les au début de build, afin que l’onglet soit à jour après chaque setState. Le corps affiche ensuite recipeList(recipes) ou recipeList(favorites), selon l’onglet.

challenge icon

Défi

Difficile

Ajoute des onglets au livre de recettes :

  • déplace le ListView.builder dans une méthode Widget recipeList(List<Recipe> shown) qui affiche shown
  • ajoute une NavigationBar avec deux onglets : Recipes (Icons.menu_book_outlined, Icons.menu_book lorsqu’il est sélectionné) et Favorites (Icons.star_border, Icons.star lorsqu’il est sélectionné), en conservant l’index de l’onglet dans l’état
  • l’onglet Recipes affiche toutes les recettes, l’onglet Favorites affiche uniquement les recettes favorites

Essayez vous-même

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final List<Recipe> recipes = [
    Recipe(name: 'Pancakes', minutes: 20, ingredients: ['Flour', 'Eggs', 'Milk', 'Butter']),
    Recipe(name: 'Tomato Soup', minutes: 35, ingredients: ['Tomatoes', 'Onion', 'Garlic', 'Olive oil']),
    Recipe(name: 'Guacamole', minutes: 10, ingredients: ['Avocados', 'Lime', 'Onion', 'Salt']),
    Recipe(name: 'Fried Rice', minutes: 25, ingredients: ['Rice', 'Eggs', 'Peas', 'Soy sauce']),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Recipe Book')),
      body: ListView.builder(
        itemCount: recipes.length,
        itemBuilder: (context, index) {
          final Recipe recipe = recipes[index];
          return ListTile(
            leading: const Icon(Icons.restaurant_menu),
            title: Text(recipe.name),
            subtitle: Text('${recipe.minutes} min'),
            onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => RecipeScreen(recipe: recipe)),
              );
            },
            trailing: IconButton(
              icon: Icon(
                recipe.favorite ? Icons.favorite : Icons.favorite_border,
                color: recipe.favorite ? Colors.red : null,
              ),
              onPressed: () {
                setState(() {
                  recipe.favorite = !recipe.favorite;
                });
              },
            ),
          );
        },
      ),
    );
  }
}

class RecipeScreen extends StatelessWidget {
  const RecipeScreen({super.key, required this.recipe});

  final Recipe recipe;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(recipe.name)),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          Text('Ready in ${recipe.minutes} minutes', style: const TextStyle(fontSize: 18)),
          const SizedBox(height: 24),
          const Text('Ingredients', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
          for (String ingredient in recipe.ingredients)
            ListTile(
              leading: const Icon(Icons.check_circle_outline),
              title: Text(ingredient),
            ),
        ],
      ),
    );
  }
}

class Recipe {
  final String name;
  final int minutes;
  final List<String> ingredients;
  bool favorite = false;

  Recipe({required this.name, required this.minutes, required this.ingredients});
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Listes et écrans

Entraînez-vous par vous-même : Compilateur Flutter en ligne