Menu
CoddyTech

Giá cả với NumberFormat

Thuộc phần Dữ liệu và mạng trong hành trình Flutter của Coddy. Bài học 22 trên 27.

Giá được gửi từ máy chủ dưới dạng số thông thường: 7.5, 12.25. Đưa 7.5 vào chuỗi, bạn sẽ có $7.5, cách hiển thị mà không cửa hàng nào dùng. Giá cần có ký hiệu tiền tệ và chính xác hai chữ số thập phân.

NumberFormat.currency, thuộc cùng package intl, làm được cả hai việc:

final price = NumberFormat.currency(symbol: '\$');
price.format(7.5)      // $7.50
price.format(1250)     // $1,250.00

Nó thêm ký hiệu, luôn hiển thị hai chữ số thập phân và đặt dấu phẩy giữa các hàng nghìn. symbol là ký hiệu cần in ra. Nếu không có ký hiệu này, bạn sẽ nhận được mã tiền tệ thay thế: USD7.50.

Dấu $ có dấu gạch chéo ngược phía trước, '\$', vì trong chuỗi Dart, $ bắt đầu một biến. Dấu gạch chéo ngược có nghĩa là “một dấu đô la thông thường”.

challenge icon

Thử thách

Dễ

Giá sách hiện là $7.5. Định dạng tất cả giá bằng NumberFormat.currency(symbol: '\$') để hiển thị lần lượt là $8.99, $7.50 và $12.25.

Tự làm thử

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

import 'api.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: BooksScreen(),
    );
  }
}

class BooksScreen extends StatefulWidget {
  const BooksScreen({super.key});

  @override
  State<BooksScreen> createState() => _BooksScreenState();
}

class _BooksScreenState extends State<BooksScreen> {
  late Future<List<Book>> _books;

  @override
  void initState() {
    super.initState();
    _books = loadBooks();
  }

  Future<List<Book>> loadBooks() async {
    final body = await fetch('/books');
    final items = jsonDecode(body) as List<dynamic>;
    return items.map((item) => Book.fromJson(item as Map<String, dynamic>)).toList();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Books')),
      body: FutureBuilder<List<Book>>(
        future: _books,
        builder: (context, snapshot) {
          if (snapshot.hasError) {
            return Center(child: Text('Could not load: ${snapshot.error}'));
          }
          if (snapshot.hasData) {
            final books = snapshot.data!;
            return ListView.builder(
              itemCount: books.length,
              itemBuilder: (context, index) {
                final book = books[index];
                return ListTile(
                  title: Text(book.title),
                  subtitle: Text(book.author),
                  trailing: Text(
                    '\$${book.price}',
                    style: const TextStyle(fontSize: 18),
                  ),
                );
              },
            );
          }
          return const Center(child: CircularProgressIndicator());
        },
      ),
    );
  }
}

class Book {
  Book({required this.title, required this.author, required this.price});

  final String title;
  final String author;
  final double price;

  factory Book.fromJson(Map<String, dynamic> json) {
    return Book(
      title: json['title'] as String,
      author: json['author'] as String,
      price: json['price'] as double,
    );
  }
}
quiz iconTự kiểm tra

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ữ liệu và mạng

Tự luyện tập: Trình biên dịch Flutter online