Tarif Kitabı: Favoriler
Coddy'nin Flutter Journey'sinin Listeler ve Ekranlar bölümünün bir parçası. Ders 31 / 33.
Bazı yemek tariflerini her hafta pişirirsin. Her satırın sonundaki bir kalp, favoriyi işaretler: favori değilse içi boş bir kalp, favoriyse kırmızı ve dolu bir kalp.
Bir tarifin favori olup olmaması tarifin bir parçasıdır, bu yüzden bir alan olur. Diğerlerinden farklı olarak değiştiği için final değildir ve başlangıç değeri false olur:
bool favorite = false;Değişen veriler setState gerektirir, bu nedenle HomeScreen bir StatefulWidget olur. Tarifler build içinden çıkıp State sınıfına taşınır: build içinde oluşturulan bir liste her setState çağrısında yeniden oluşturulur ve bütün kalplerin içi boşalır.
Kalp bir IconButton'dır. Simgesi, ? : ile dolu ya da boş kalbi seçer; düğmeye basıldığında alanın değeri tersine çevrilir: recipe.favorite = !recipe.favorite.
Görev
ZorHer tarife bir favori kalbi ekle:
Recipesınıfınabool favorite = false;alanını ekleHomeScreen'i birStatefulWidget'a dönüştür ve tarifler listesiniStatesınıfına taşı- Her kutucuğa,
Icons.favorite_bordergösteren birtrailing:IconButtonekle; tarif favoriyse bunun yerine kırmızı birIcons.favoritegöster. Düğmeye basıldığındafavoritedeğerini tersine çevir
Kendin dene
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});
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Listeler ve Ekranlar bölümündeki tüm dersler
1Kaydırılabilir Listeler
Kaydırılan Bir ListeListe ÖğeleriBaş ve SonBir Liste Öğesine DokunmaSatırlar Arasındaki Ayraçlar4Kendi Sınıflarınız
Verileriniz İçin Bir SınıfAdlandırılmış ve Zorunlu ParametrelerBoş Bırakılabilen Alanlarmap ile Verilerden Widget'larwhere ile Bir Listeyi FiltrelemeBir Map'te Arama7Proje: Tarif Kitabı
Tarif Kitabı: Tarif ListesiTarif Kitabı: Tarif Ekranı6Sekmeler, Çekmeceler ve Kaydırma Hareketleri
Gezinme Çubuğuyla SekmelerAçık Sekme İçin Dolu SimgelerYan ÇekmeceSilmek İçin KaydırınKaydırmayı Geri AlınKendi başına pratik yap: Online Flutter derleyicisi