Libro de recetas: Aún no hay favoritos
Parte de la sección Listas y pantallas del Journey de Flutter de Coddy. Lección 33 de 33.
Abre la pestaña Favoritos antes de marcar algo con un corazón: la pantalla está en blanco, y una pantalla en blanco parece estar rota. Una lista vacía debería indicar por qué está vacía.
La propiedad isEmpty de una lista es true cuando no tiene elementos. Elige la página en build con un if, antes del return:
Widget page;
if (index == 0) {
page = recipeList(recipes);
} else if (favorites.isEmpty) {
page = const Center(child: Text('No favorites yet'));
} else {
page = recipeList(favorites);
}Una variable de tipo Widget puede contener cualquier widget, así que page es una lista en una rama y un mensaje en otra. El cuerpo de Scaffold es entonces page.
Desafío
FácilCuando la pestaña Favoritos no tenga nada que mostrar, muestra No favorites yet en el centro de la pantalla, con tamaño 18, en lugar de la lista vacía. Cuando marques una receta como favorita, volverá a aparecer en la pestaña.
Pruébalo tú mismo
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});
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Listas y pantallas
1Listas con desplazamiento
Una lista desplazableElementos de listaAl principio y al finalToca un elemento de listaSeparadores entre filas4Tus propias clases
Una clase para tus datosParámetros con nombre y obligatoriosCampos que pueden estar vacíosWidgets a partir de datos con mapFiltrar una lista con whereBuscar en un mapa7Proyecto: Libro de recetas
Libro de recetas: La lista de recetasLibro de recetas: La pantalla de la receta3Tarjetas y cuadrículas
Tarjetas en una listaUna cuadrícula de mosaicosUna cuadrícula creada con un constructor6Pestañas, cajones y deslizamientos
Pestañas con una barra de navegaciónIconos rellenos para la pestaña abiertaUn cajón lateralDeslizar para eliminarDeshacer un deslizamientoPractica por tu cuenta: Compilador de Flutter online