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.
Aufgabe
SchwerFüge jedem Rezept ein Favoritenherz hinzu:
- Füge
Recipeein Feldbool favorite = false;hinzu - Wandle
HomeScreenin einStatefulWidgetum und verschiebe die Rezeptliste in seineState-Klasse - Füge jeder Kachel ein
trailing:IconButtonhinzu, dasIcons.favorite_borderanzeigt oder ein rotesIcons.favorite, wenn das Rezept ein Favorit ist. Beim Drücken wirdfavoriteumgeschaltet
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});
}
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
1Scrollbare Listen
Eine scrollbare ListeListenelementeVorne und hintenEin Listenelement antippenTrennlinien zwischen Zeilen4Deine eigenen Klassen
Eine Klasse für deine DatenBenannte und erforderliche ParameterFelder, die leer sein könnenWidgets aus Daten mit mapEine Liste mit where filternIn einer Map nachschlagen7Projekt: Rezeptbuch
Rezeptbuch: Die RezeptlisteRezeptbuch: Der RezeptbildschirmÜbe selbstständig: Online-Flutter-Compiler