Toko: Detail Produk
Termasuk bagian Proyek dalam perjalanan Flutter di Coddy. Pelajaran 21 dari 36.
Ketuk produk di toko dan kamu akan membuka halamannya: gambar besar, harga, dan beberapa kata tentang produk itu. Itu adalah layar kedua, ProductScreen, yang menerima produk melalui konstruktornya.
Agar seluruh kartu bisa diketuk, letakkan InkWell di dalam Card, mengelilingi kontennya. Widget ini menjalankan onTap dan menggambar efek riak yang kamu lihat di aplikasi Material; Clip.antiAlias pada kartu menjaga efek riak tetap berada di dalam sudut yang membulat.
Card(
clipBehavior: Clip.antiAlias,
child: InkWell(
onTap: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) => ProductScreen(product: product),
));
},
child: Column(...),
),
)Halaman produk menggunakan ListView, sehingga deskripsi yang panjang bisa digulir. AppBar-nya menampilkan nama produk dan panah kembali, yang ditambahkan Flutter untukmu pada layar yang dibuka dengan push.
Untuk harga yang besar, mulai dari headlineSmall pada tema, lalu ubah hanya bagian yang kamu perlukan dengan copyWith: textTheme.headlineSmall?.copyWith(fontWeight: FontWeight.bold). ?. digunakan karena gaya tema bisa bernilai null.
Tantangan
SedangBuat halaman untuk setiap produk:
- tulis
ProductScreenyang menerimarequiredproduct, dengan nama diAppBar - body-nya berupa
ListViewdengan padding 24 piksel: ubin setinggi 240 piksel diproduct.color.shade50dengan sudut membulat sebesar 24 dan ikon berukuran 120, lalu 24 piksel, harga (headlineSmalltebal dengan warna utama), 12 piksel, dan deskripsi dibodyLarge - bungkus
Columnsetiap kartu denganInkWellyang membuka halaman produk tersebut
Coba sendiri
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
void main() {
runApp(const MyApp());
}
final money = NumberFormat.currency(locale: 'en_US', symbol: '\$');
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.orange),
),
home: const ShopScreen(),
);
}
}
class Product {
const Product({
required this.name,
required this.price,
required this.icon,
required this.color,
required this.description,
});
final String name;
final double price;
final IconData icon;
final MaterialColor color;
final String description;
}
const List<Product> products = [
Product(
name: 'Headphones',
price: 59,
icon: Icons.headphones,
color: Colors.indigo,
description: 'Wireless headphones with 30 hours of battery.',
),
Product(
name: 'Watch',
price: 129,
icon: Icons.watch,
color: Colors.teal,
description: 'A smart watch that counts your steps.',
),
Product(
name: 'Backpack',
price: 45.5,
icon: Icons.backpack,
color: Colors.orange,
description: 'Room for a laptop, a lunch and a jacket.',
),
Product(
name: 'Mug',
price: 12,
icon: Icons.coffee,
color: Colors.brown,
description: 'Holds a big coffee and keeps it warm.',
),
Product(
name: 'Camera',
price: 1299,
icon: Icons.photo_camera,
color: Colors.blueGrey,
description: 'A mirrorless camera for sharp photos.',
),
Product(
name: 'Sneakers',
price: 89.99,
icon: Icons.directions_run,
color: Colors.red,
description: 'Light running shoes for every day.',
),
];
class ShopScreen extends StatelessWidget {
const ShopScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Coddy Shop')),
body: GridView.count(
crossAxisCount: 2,
padding: const EdgeInsets.all(16),
mainAxisSpacing: 12,
crossAxisSpacing: 12,
childAspectRatio: 0.8,
children: [
for (Product product in products) ProductCard(product: product),
],
),
);
}
}
class ProductCard extends StatelessWidget {
const ProductCard({super.key, required this.product});
final Product product;
@override
Widget build(BuildContext context) {
return Card(
clipBehavior: Clip.antiAlias,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Container(
width: double.infinity,
alignment: Alignment.center,
color: product.color.shade50,
child: Icon(product.icon, size: 56, color: product.color),
),
),
Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
product.name,
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 4),
Text(
money.format(product.price),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.primary,
),
),
],
),
),
],
),
);
}
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Proyek
1Proyek: Daftar Tugas
Daftar Tugas: Daftar TugasDaftar Tugas: Tambahkan Tugas4Proyek: Pelacak Kebiasaan
Pelacak Kebiasaan: KebiasaanmuPelacak Kebiasaan: Pekan IniLatihan sendiri: Compiler Flutter online