Cửa hàng: Giá cả
Thuộc phần Dự án trong hành trình Flutter của Coddy. Bài học 20 trên 36.
Giá 45.5 sẽ hiển thị là $45.50, còn 1299 sẽ hiển thị là $1,299.00. Tự viết định dạng này khá phiền; intl có thể làm việc đó bằng NumberFormat, thống nhất cho mọi mức giá.
Tạo một bộ định dạng dùng cho toàn ứng dụng ở đầu tệp, rồi dùng ở mọi nơi hiển thị giá:
import 'package:intl/intl.dart';
final money = NumberFormat.currency(locale: 'en_US', symbol: '\$');
money.format(1299); // $1,299.00locale: 'en_US' quyết định cách viết số: dấu phẩy ngăn cách hàng nghìn và dấu chấm đứng trước phần xu. Với de_DE, cùng mức giá đó sẽ là 1.299,00. symbol là ký hiệu đứng phía trước; trong Dart, $ trong chuỗi bắt đầu phép nội suy, vì vậy hãy viết là '\$'.
Bên dưới mỗi tên, hãy hiển thị giá đã định dạng bằng chữ đậm và màu primary của giao diện để giá nổi bật hơn tên.
Thử thách
DễHiển thị giá:
- import
package:intl/intl.dartrồi thêm bộ định dạngmoneytừ phần lý thuyết phía trênMyApp - bên dưới tên trên mỗi thẻ, cách xuống 4 pixel, hiển thị
money.format(product.price), in đậm, bằngTheme.of(context).colorScheme.primary
Tự làm thử
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
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: Text(
product.name,
style: Theme.of(context).textTheme.titleMedium,
),
),
],
),
);
}
}
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Dự án
1Dự án: Danh sách việc cần làm
Danh sách việc cần làm: Danh sách công việcDanh sách việc cần làm: Thêm công việc4Dự án: Theo dõi thói quen
Theo dõi thói quen: Thói quen của bạnTheo dõi thói quen: TuầnTự luyện tập: Trình biên dịch Flutter online