Menu
CoddyTech

ストア:価格

CoddyのFlutterジャーニー「プロジェクト」セクションの一部。レッスン 20/36。

45.5は$45.50と表示し、1299は$1,299.00と表示します。手作業で書くのは面倒ですが、intlのNumberFormatを使えば、どの価格も同じ方法で表示できます。

ファイルの先頭でアプリ全体用のフォーマッターを1つ作り、価格を表示する場所すべてで使いましょう。

import 'package:intl/intl.dart';

final money = NumberFormat.currency(locale: 'en_US', symbol: '\$');

money.format(1299); // $1,299.00

locale: 'en_US'は数値の表記方法を指定します。千の位の区切りにはカンマを使い、セントの前にはピリオドを置きます。de_DEでは、同じ価格は1.299,00となります。symbolは先頭に付ける記号です。Dartでは文字列内の$は補間を開始するため、'\$'と書きます。

それぞれの名前の下に、フォーマットした価格を太字でテーマのprimary色で表示し、価格が名前より目立つようにしましょう。

challenge icon

チャレンジ

簡単

価格を表示します:

  • package:intl/intl.dartをimportし、上記の理論にあるMyAppの上にmoneyフォーマッターを追加します
  • 各カードの商品名の下に4ピクセル空けて、money.format(product.price)を太字でTheme.of(context).colorScheme.primaryの色で表示します

自分で試してみよう

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,
            ),
          ),
        ],
      ),
    );
  }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

プロジェクトのすべてのレッスン

自分で練習してみよう: Flutterオンラインコンパイラ