Menu
CoddyTech

Boutique : la grille de produits

Fait partie de la section Projets du Journey Flutter de Coddy. Leçon 19 sur 36.

La troisième application est une petite boutique : une grille de produits, une page pour chacun, un panier et une validation de commande. C’est la forme que prennent la plupart des applications d’achat, et elle remet Provider et intl au programme.

Les produits sont fournis dans le projet de départ, chacun avec un nom, un prix, une icône, une couleur et une description. Une boutique les affiche dans une grille, deux par rangée sur un téléphone :

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)],
)

childAspectRatio correspond à la largeur divisée par la hauteur : 0.8 rend chaque carte un peu plus haute que large, avec assez de place pour une image et deux lignes de texte.

Chaque carte est son propre widget, ProductCard, qui reçoit un Product. À l’intérieur, une tuile Expanded occupe l’espace au-dessus du nom. Sa couleur est la nuance la plus claire de la couleur du produit, product.color.shade50, avec l’icône en couleur pleine par-dessus. C’est pourquoi color est un MaterialColor : il possède plusieurs nuances.

challenge icon

Défi

Moyen

Affiche les produits :

  • écris un widget ProductCard qui prend un product required
  • c’est une Card (avec clipBehavior: Clip.antiAlias) contenant une Column : un Container Expanded en pleine largeur, de couleur product.color.shade50, avec l’icône du produit au centre (taille 56, product.color), puis le nom en titleMedium avec une marge intérieure de 12 pixels
  • remplace le Center par le GridView.count présenté dans la théorie

Essayez vous-même

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: const Center(
        child: Text('Products go here'),
      ),
    );
  }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Projets

Entraînez-vous par vous-même : Compilateur Flutter en ligne