Sổ tay công thức nấu ăn: Tab mục yêu thích
Thuộc phần Danh sách và màn hình trong hành trình Flutter của Coddy. Bài học 32 trên 33.
Trái tim chỉ hữu ích khi bạn có thể tìm lại những món yêu thích. Tab thứ hai, Favorites, chỉ hiển thị các công thức nấu ăn có trái tim màu đỏ.
Cả hai tab đều hiển thị danh sách công thức nấu ăn giống nhau, vì vậy hãy viết danh sách một lần dưới dạng phương thức nhận các công thức cần hiển thị:
Widget recipeList(List<Recipe> shown) {
return ListView.builder(...);
}Các món yêu thích là những công thức nấu ăn where favorite có giá trị true. Hãy xác định chúng ở đầu build để tab được cập nhật sau mỗi setState. Sau đó, phần nội dung sẽ hiển thị recipeList(recipes) hoặc recipeList(favorites), tùy theo tab.
Thử thách
KhóThêm các thẻ vào sách công thức:
- chuyển
ListView.buildervào phương thứcWidget recipeList(List<Recipe> shown)để liệt kêshown - thêm
NavigationBarvới hai thẻ:Recipes(Icons.menu_book_outlined,Icons.menu_bookkhi được chọn) vàFavorites(Icons.star_border,Icons.starkhi được chọn), đồng thời giữindexcủa thẻ trong trạng thái - thẻ Recipes liệt kê mọi công thức, thẻ Favorites chỉ liệt kê các công thức yêu thích
Tự làm thử
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});
}
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Danh sách và màn hình
1Danh sách cuộn
Danh sách có thể cuộnÔ danh sáchPhần đầu và phần cuốiChạm vào một ô danh sáchĐường phân cách giữa các hàng4Các lớp của riêng bạn
Một lớp cho dữ liệu của bạnTham số có tên và bắt buộcCác trường có thể để trốngTạo widget từ dữ liệu bằng mapLọc danh sách bằng whereTra cứu trong Map7Dự án: Sổ tay công thức nấu ăn
Sổ tay công thức nấu ăn: Danh sách công thứcSổ tay công thức nấu ăn: Màn hình công thức5Nhiều hơn một màn hình
Mở màn hình mớiMũi tên quay lạiQuay lại bằng nútGửi dữ liệu đến màn hìnhNhận lại kết quả6Tab, ngăn kéo và thao tác vuốt
Tab với thanh điều hướngBiểu tượng tô kín cho tab đang mởNgăn kéo bênVuốt để xóaHoàn tác thao tác vuốtTự luyện tập: Trình biên dịch Flutter online