Menu
CoddyTech

Rezeptbuch: Favoriten-Tab

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

Herzen sind nur nützlich, wenn du deine Favoriten wiederfinden kannst. Ein zweiter Tab, Favorites, zeigt nur die Rezepte mit einem roten Herzen.

Beide Tabs zeigen eine gleich aussehende Rezeptliste. Schreibe die Liste daher nur einmal, als Methode, die die anzuzeigenden Rezepte entgegennimmt:

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

Die Favoriten sind die Rezepte, für die where favorite true ist. Ermittle sie oben in build, damit der Tab nach jedem setState stimmt. Der Inhalt zeigt dann recipeList(recipes) oder recipeList(favorites), abhängig vom Tab.

challenge icon

Aufgabe

Schwer

Füge dem Rezeptbuch Tabs hinzu:

  • verschiebe ListView.builder in eine Methode Widget recipeList(List<Recipe> shown), die shown auflistet
  • füge eine NavigationBar mit zwei Tabs hinzu: Recipes (Icons.menu_book_outlined, Icons.menu_book bei Auswahl) und Favorites (Icons.star_border, Icons.star bei Auswahl), wobei der index des Tabs im Zustand gespeichert wird
  • der Tab „Recipes“ listet alle Rezepte auf, der Tab „Favorites“ nur die Favoriten

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 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 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