كتاب الوصفات: لا توجد وصفات مفضلة بعد
جزء من قسم القوائم والشاشات في رحلة Flutter على Coddy. الدرس 33 من 33.
افتح علامة تبويب المفضّلة قبل إضافة أي شيء إليها: الشاشة فارغة، والشاشة الفارغة تبدو معطّلة. ينبغي أن توضّح القائمة الفارغة سبب خلوّها.
تكون isEmpty للقائمة true عندما لا تحتوي على أي عناصر. اختر الصفحة في build باستخدام if، قبل 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);
}يمكن لمتغيّر من النوع Widget أن يحتوي على أي عنصر واجهة مستخدم، لذا تكون page قائمة في أحد الفرعين ورسالة في الفرع الآخر. ويكون page عندئذٍ هو محتوى Scaffold.
التحدي
سهلعندما لا يحتوي تبويب المفضّلة على شيء لعرضه، اعرض No favorites yet في منتصف الشاشة بحجم 18، بدلًا من القائمة الفارغة. بمجرد إضافة وصفة إلى المفضّلة، يعرضها التبويب مجددًا.
جرّب بنفسك
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});
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس القوائم والشاشات
1قوائم قابلة للتمرير
قائمة قابلة للتمريرعناصر القائمةالبداية والنهايةاضغط على عنصر قائمةفواصل بين الصفوف4أصنافك الخاصة
صنف لبياناتكالمعاملات المُسمّاة والإلزاميةحقول يمكن أن تكون فارغةعناصر واجهة من البيانات باستخدام mapتصفية قائمة باستخدام whereالبحث في Map7المشروع: كتاب الوصفات
كتاب الوصفات: قائمة الوصفاتكتاب الوصفات: شاشة الوصفة6علامات التبويب والأدراج والتمرير بالسحب
علامات التبويب مع شريط تنقلأيقونات ممتلئة لعلامة التبويب المفتوحةدرج جانبياسحب للحذفالتراجع عن السحبتدرّب بنفسك: مترجم Flutter عبر الإنترنت