Buku Resep: Favorit
Termasuk bagian List dan Layar dalam perjalanan Flutter di Coddy. Pelajaran 31 dari 33.
Beberapa resep kamu masak setiap minggu. Ikon hati di ujung setiap baris menandai resep favorit: hati kosong jika bukan favorit, dan hati merah terisi jika favorit.
Status favorit resep merupakan bagian dari resep, jadi status itu menjadi sebuah field. Tidak seperti field lainnya, nilainya berubah, jadi field ini bukan final, dan nilai awalnya false:
bool favorite = false;Data yang berubah memerlukan setState, jadi HomeScreen menjadi StatefulWidget. Resep dipindahkan dari build ke dalam class State: list yang dibuat di dalam build akan dibuat lagi setiap kali setState dipanggil, sehingga semua ikon hati akan kembali kosong.
Ikon hati adalah IconButton. Ikonnya memilih hati terisi atau kosong dengan ? :, dan saat ditekan, nilainya dibalik: recipe.favorite = !recipe.favorite.
Tantangan
SulitTambahkan ikon hati favorit pada setiap resep:
- tambahkan field
bool favorite = false;keRecipe - ubah
HomeScreenmenjadiStatefulWidgetdan pindahkan daftar resep ke classState-nya - tambahkan
trailing:berupaIconButtonpada setiap tile yang menampilkanIcons.favorite_border, atauIcons.favoriteberwarna merah saat resep menjadi favorit. Menekannya akan membalik nilaifavorite
Coba sendiri
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});
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di List dan Layar
1Daftar yang Dapat Digulir
Daftar yang Bisa DigulirItem DaftarBagian Awal dan AkhirKetuk Item DaftarPemisah Antarbaris4Class Milikmu Sendiri
Class untuk DatamuParameter Bernama dan WajibField yang Bisa KosongWidget dari Data dengan mapFilter List dengan whereCari di Map7Proyek: Buku Resep
Buku Resep: Daftar ResepBuku Resep: Layar ResepLatihan sendiri: Compiler Flutter online