Menu
CoddyTech

Ricettario: la scheda dei preferiti

Fa parte della sezione Elenchi e schermate del percorso Flutter di Coddy. Lezione 32 di 33.

I cuori sono utili solo se riesci a ritrovare i tuoi preferiti. Una seconda scheda, Favorites, mostra solo le ricette con un cuore rosso.

Entrambe le schede mostrano un elenco di ricette dall’aspetto identico, quindi scrivi l’elenco una sola volta, come metodo che accetta le ricette da mostrare:

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

Le ricette preferite sono quelle per cui where favorite è true. Calcolale all’inizio di build, in modo che la scheda sia corretta dopo ogni setState. Il corpo mostra quindi recipeList(recipes) oppure recipeList(favorites), a seconda della scheda.

challenge icon

Sfida

Difficile

Aggiungi delle schede al ricettario:

  • sposta il ListView.builder in un metodo Widget recipeList(List<Recipe> shown) che elenca shown
  • aggiungi una NavigationBar con due schede: Recipes (Icons.menu_book_outlined, Icons.menu_book quando selezionata) e Favorites (Icons.star_border, Icons.star quando selezionata), mantenendo lo index della scheda nello stato
  • la scheda Recipes elenca tutte le ricette, mentre la scheda Favorites mostra solo le preferite

Provalo tu

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 iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Elenchi e schermate

Esercitati da solo: Compilatore Flutter online