Building a Product List App in Flutter: Fetching Data, Displaying Cards, and Grid View

Spread the love

Learn how to build a product list app in Flutter using HTTP requests to fetch data, displaying product cards with images, titles, prices, and discounts. Explore different layouts like ListView and GridView, and enhance the app with rounded corners and discount badges. This beginner-friendly tutorial will guide you through the process of creating a dynamic and visually appealing product list for your Flutter applications.

Building a Product List App in Flutter: Fetching Data, Displaying Cards, and Grid View
Building a Product List App in Flutter: Fetching Data, Displaying Cards, and Grid View

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Product List Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<dynamic> _products = [];

  @override
  void initState() {
    super.initState();
    fetchProducts();
  }

  Future<void> fetchProducts() async {
    var url = Uri.parse('https://dummyjson.com/products');
    var response = await http.get(url);

    setState(() {
      if (response.statusCode == 200) {
        // Successful request
        var data = json.decode(response.body);
        _products = data['products'];
      } else {
        // Request failed
        _products = [];
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Product List'),
      ),
      body: GridView.builder(
        padding: EdgeInsets.all(8),
        itemCount: _products.length,
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
          crossAxisSpacing: 8,
          mainAxisSpacing: 8,
          childAspectRatio: 0.7,
        ),
        itemBuilder: (context, index) {
          var product = _products[index];
          var thumbnailUrl = product['thumbnail'];
          var discount = product['discountPercentage'];

          return Card(
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(10),
            ),
            elevation: 4,
            child: Column(
              children: [
                Expanded(
                  flex: 3,
                  child: Stack(
                    children: [
                      ClipRRect(
                        borderRadius: BorderRadius.vertical(
                          top: Radius.circular(10),
                        ),
                        child: Image.network(
                          thumbnailUrl,
                          width: double.infinity,
                          fit: BoxFit.cover,
                        ),
                      ),
                      if (discount != null)
                        Positioned(
                          top: 8,
                          right: 8,
                          child: Container(
                            padding: EdgeInsets.symmetric(
                              vertical: 4,
                              horizontal: 8,
                            ),
                            decoration: BoxDecoration(
                              color: Colors.red,
                              borderRadius: BorderRadius.circular(8),
                            ),
                            child: Text(
                              '${discount.toStringAsFixed(2)}% OFF',
                              style: TextStyle(
                                color: Colors.white,
                                fontWeight: FontWeight.bold,
                                fontSize: 12,
                              ),
                            ),
                          ),
                        ),
                    ],
                  ),
                ),
                Expanded(
                  flex: 2,
                  child: ListTile(
                    title: Text(
                      product['title'],
                      style: TextStyle(
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    subtitle: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text('Price: \$${product['price']}'),
                        if (discount != null)
                          Text('Discount: ${discount.toStringAsFixed(2)}%'),
                        if (product['stock'] == 0)
                          Text(
                            'Out of Stock',
                            style: TextStyle(
                              color: Colors.red,
                            ),
                          ),
                      ],
                    ),
                  ),
                ),
              ],
            ),
          );
        },
      ),
    );
  }
}

In this updated code, a Card widget is used to wrap each product, and the Card is given rounded corners using the borderRadius property. The product image is displayed using the Image.network widget within a ClipRRect to achieve rounded top corners. If the product has a discount, a Positioned widget is used to place a Container with the discount text as a badge on the top right corner of the image.

You can run this code in a Flutter project to see the list of products fetched from the API displayed in a Card format, with rounded corners and the discount badge displayed on top of the product image.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *