Menu
CoddyTech

Rezeptbuch: Favoriten

Teil des Abschnitts Listen und Bildschirme der Flutter-Journey von Coddy. Lektion 31 von 33.

Einige Rezepte kochst du jede Woche. Ein Herz am Ende jeder Zeile kennzeichnet einen Favoriten: ein leeres Herz, wenn es keiner ist, und ein ausgefülltes rotes Herz, wenn es einer ist.

Ob ein Rezept ein Favorit ist, gehört zum Rezept und wird deshalb zu einem Feld. Anders als die anderen ändert es sich, daher ist es nicht final, und es beginnt mit false:

bool favorite = false;

Daten, die sich ändern, benötigen setState, daher wird HomeScreen zu einem StatefulWidget. Die Rezepte wandern aus build in die State-Klasse: Eine innerhalb von build erstellte Liste wird bei jedem setState erneut erstellt, und jedes Herz würde wieder leer werden.

Das Herz ist ein IconButton. Sein Symbol wählt mit ? : das ausgefüllte oder das leere Herz aus, und beim Drücken wird das Feld umgeschaltet: recipe.favorite = !recipe.favorite.

challenge icon

Aufgabe

Schwer

Füge jedem Rezept ein Favoritenherz hinzu:

  • Füge Recipe ein Feld bool favorite = false; hinzu
  • Wandle HomeScreen in ein StatefulWidget um und verschiebe die Rezeptliste in seine State-Klasse
  • Füge jeder Kachel ein trailing: IconButton hinzu, das Icons.favorite_border anzeigt oder ein rotes Icons.favorite, wenn das Rezept ein Favorit ist. Beim Drücken wird favorite umgeschaltet

Probier es selbst

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 StatelessWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    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']),
    ];
    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)),
              );
            },
          );
        },
      ),
    );
  }
}

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;

  Recipe({required this.name, required this.minutes, required this.ingredients});
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Listen und Bildschirme

Übe selbstständig: Online-Flutter-Compiler