Sklep: Szczegóły produktu
Część sekcji Projekty ścieżki Flutter w Coddy. Lekcja 21 z 36.
Gdy stukniesz produkt w sklepie, otworzy się jego strona: duże zdjęcie, cena i kilka słów na jego temat. To drugi ekran, ProductScreen, który otrzymuje produkt za pośrednictwem konstruktora.
Aby można było stuknąć całą kartę, umieść InkWell wewnątrz Card, wokół jej zawartości. Uruchamia on onTap i rysuje falę, którą widzisz w aplikacjach Material; Clip.antiAlias karty utrzymuje falę wewnątrz zaokrąglonych rogów.
Card(
clipBehavior: Clip.antiAlias,
child: InkWell(
onTap: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) => ProductScreen(product: product),
));
},
child: Column(...),
),
)Strona produktu to ListView, więc długi opis można przewijać. Jej AppBar wyświetla nazwę produktu i strzałkę wstecz, którą Flutter dodaje automatycznie na ekranie otwartym przez nawigację.
W przypadku dużej ceny zacznij od stylu headlineSmall z motywu i zmień tylko to, czego potrzebujesz, za pomocą copyWith: textTheme.headlineSmall?.copyWith(fontWeight: FontWeight.bold). ?. jest tam dlatego, że styl motywu może mieć wartość null.
Wyzwanie
ŚredniUtwórz stronę dla każdego produktu:
- napisz
ProductScreen, który przyjmuje wymaganyproduct, a jego nazwę wyświetla wAppBar - jego treść to
ListViewz marginesem wewnętrznym 24 pikseli: kafelek o wysokości 240 pikseli w kolorzeproduct.color.shade50, z zaokrąglonymi narożnikami o promieniu 24 pikseli i ikoną w rozmiarze 120, następnie 24 piksele odstępu, cena (pogrubioneheadlineSmallw kolorze głównym), 12 pikseli odstępu i opis w stylubodyLarge - owijaj
Columnkażdej karty wInkWell, który otwiera stronę produktu
Spróbuj swoich sił
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,
),
),
],
),
),
],
),
);
}
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Projekty
3Projekt: Sklep
Sklep: Siatka produktówSklep: CenyPoćwicz samodzielnie: Kompilator Flutter online