Rezeptbuch: Noch keine Favoriten
Teil des Abschnitts Listen und Bildschirme der Flutter-Journey von Coddy. Lektion 33 von 33.
Öffne den Favoriten-Tab, bevor du etwas mit einem Herz markierst: Der Bildschirm ist leer, und ein leerer Bildschirm wirkt kaputt. Eine leere Liste sollte erklären, warum sie leer ist.
Die Eigenschaft isEmpty einer Liste ist true, wenn sie keine Elemente enthält. Wähle die Seite in build mit einem if vor dem return aus:
Widget page;
if (index == 0) {
page = recipeList(recipes);
} else if (favorites.isEmpty) {
page = const Center(child: Text('No favorites yet'));
} else {
page = recipeList(favorites);
}Eine Variable vom Typ Widget kann ein beliebiges Widget enthalten, daher ist page in einem Zweig eine Liste und in einem anderen eine Nachricht. Der Body von Scaffold ist dann page.
Aufgabe
EinfachWenn der Tab „Favorites“ nichts anzuzeigen hat, zeige No favorites yet in der Bildschirmmitte in Schriftgröße 18 an, anstelle der leeren Liste. Sobald ein Rezept als Favorit markiert wurde, wird es wieder im Tab aufgeführt.
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']),
];
int index = 0;
Widget recipeList(List<Recipe> shown) {
return ListView.builder(
itemCount: shown.length,
itemBuilder: (context, i) {
final Recipe recipe = shown[i];
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;
});
},
),
);
},
);
}
@override
Widget build(BuildContext context) {
final List<Recipe> favorites = recipes.where((recipe) => recipe.favorite).toList();
return Scaffold(
appBar: AppBar(title: const Text('Recipe Book')),
body: index == 0 ? recipeList(recipes) : recipeList(favorites),
bottomNavigationBar: NavigationBar(
selectedIndex: index,
onDestinationSelected: (int i) {
setState(() {
index = i;
});
},
destinations: const [
NavigationDestination(
icon: Icon(Icons.menu_book_outlined),
selectedIcon: Icon(Icons.menu_book),
label: 'Recipes',
),
NavigationDestination(
icon: Icon(Icons.star_border),
selectedIcon: Icon(Icons.star),
label: 'Favorites',
),
],
),
);
}
}
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});
}
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