image

17 Feb 2026

9K

35K

Building a Product Review List Widget with Rating Stars in Flutter

Enhancing user trust and driving sales are crucial for any e-commerce application. A well-designed product review section, complete with star ratings, provides valuable social proof and helps potential customers make informed decisions. This article will guide you through creating a professional and reusable Product Review List widget in Flutter, featuring interactive rating stars.

1. Defining the Review Data Model

First, let's create a simple Dart class to represent a single product review. This model will hold information such as the reviewer's name, their rating, the review comment, and the date.


class ProductReview {
  final String reviewerName;
  final double rating; // e.g., 4.5
  final String comment;
  final DateTime reviewDate;

  ProductReview({
    required this.reviewerName,
    required this.rating,
    required this.comment,
    required this.reviewDate,
  });
}

2. Creating a Reusable Rating Stars Widget

A dedicated widget for displaying star ratings ensures consistency and reusability. We'll use a row of Icon widgets to represent the stars, coloring them based on the provided rating.


import 'package:flutter/material.dart';

class RatingStars extends StatelessWidget {
  final double rating;
  final double size;
  final Color color;

  const RatingStars({
    Key? key,
    required this.rating,
    this.size = 20.0,
    this.color = Colors.amber,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: List.generate(5, (index) {
        return Icon(
          index < rating.floor()
              ? Icons.star
              : (index < rating && rating % 1 != 0 ? Icons.star_half : Icons.star_border),
          color: color,
          size: size,
        );
      }),
    );
  }
}

3. Building the Individual Review Item Widget

Now, let's create a widget that displays a single product review, incorporating the RatingStars widget we just built. This widget will show the reviewer's name, the star rating, the review date, and the comment. Remember to add the intl package to your pubspec.yaml for date formatting (intl: ^0.18.0 or higher).


import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; // For date formatting
// Assuming RatingStars and ProductReview are in the same project structure
// import 'rating_stars.dart';
// import 'product_review_model.dart';

class ReviewItem extends StatelessWidget {
  final ProductReview review;

  const ReviewItem({Key? key, required this.review}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Card(
      margin: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(
                  review.reviewerName,
                  style: const TextStyle(
                    fontWeight: FontWeight.bold,
                    fontSize: 16.0,
                  ),
                ),
                Text(
                  DateFormat('MMM dd, yyyy').format(review.reviewDate),
                  style: TextStyle(
                    color: Colors.grey[600],
                    fontSize: 12.0,
                  ),
                ),
              ],
            ),
            const SizedBox(height: 8.0),
            RatingStars(rating: review.rating),
            const SizedBox(height: 8.0),
            Text(
              review.comment,
              style: const TextStyle(fontSize: 14.0),
            ),
          ],
        ),
      ),
    );
  }
}

4. Assembling the Product Review List Widget

Finally, we'll create the main widget that displays a list of ReviewItem widgets. We'll use a ListView.builder for efficient rendering of potentially many reviews. If this list is nested within another scrollable widget (like SingleChildScrollView), consider setting shrinkWrap: true and physics: const NeverScrollableScrollPhysics() to prevent scrolling conflicts.


import 'package:flutter/material.dart';
// import 'product_review_model.dart';
// import 'review_item_widget.dart';

class ProductReviewList extends StatelessWidget {
  final List reviews;

  const ProductReviewList({Key? key, required this.reviews}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    if (reviews.isEmpty) {
      return const Center(
        child: Padding(
          padding: EdgeInsets.all(16.0),
          child: Text(
            'No reviews yet. Be the first to review!',
            style: TextStyle(fontSize: 16.0, color: Colors.grey),
          ),
        ),
      );
    }

    return ListView.builder(
      shrinkWrap: true, // Important if nested inside another scrollable widget
      physics: const NeverScrollableScrollPhysics(), // Important if nested inside another scrollable widget
      itemCount: reviews.length,
      itemBuilder: (context, index) {
        return ReviewItem(review: reviews[index]);
      },
    );
  }
}

5. Integrating into Your Flutter Application

To see our widget in action, let's create some sample data and display the ProductReviewList within a simple Flutter screen. For a complete example, ensure all the previously defined classes (ProductReview, RatingStars, ReviewItem, ProductReviewList) are either in the same file or correctly imported.


import 'package:flutter/material.dart';
// Assuming all previous widgets and models are accessible via imports
// import 'product_review_model.dart';
// import 'rating_stars.dart';
// import 'review_item.dart';
// import 'product_review_list.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Product Reviews Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: const ProductReviewsScreen(),
    );
  }
}

class ProductReviewsScreen extends StatelessWidget {
  const ProductReviewsScreen({Key? key}) : super(key: key);

  // Sample data
  static final List _sampleReviews = [
    ProductReview(
      reviewerName: 'Alice Smith',
      rating: 4.5,
      comment: 'Great product! Exceeded my expectations. Highly recommend.',
      reviewDate: DateTime(2023, 10, 26),
    ),
    ProductReview(
      reviewerName: 'Bob Johnson',
      rating: 3.0,
      comment: 'It\'s okay. Does the job, but nothing extraordinary.',
      reviewDate: DateTime(2023, 9, 15),
    ),
    ProductReview(
      reviewerName: 'Charlie Brown',
      rating: 5.0,
      comment: 'Absolutely perfect! Love it!',
      reviewDate: DateTime(2023, 11, 1),
    ),
    ProductReview(
      reviewerName: 'Diana Prince',
      rating: 2.5,
      comment: 'A bit disappointed with the quality. Expected more for the price.',
      reviewDate: DateTime(2023, 8, 10),
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Product Reviews'),
      ),
      body: SingleChildScrollView( // Allows the entire screen to scroll if content exceeds space
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Padding(
              padding: EdgeInsets.all(16.0),
              child: Text(
                'Customer Reviews',
                style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.bold),
              ),
            ),
            ProductReviewList(reviews: _sampleReviews),
            const SizedBox(height: 20.0), // Some bottom padding
            // Potentially other product details or UI elements here
          ],
        ),
      ),
    );
  }
}

Conclusion

Building a product review list with star ratings in Flutter is straightforward once you break it down into modular components. By creating a clear data model and reusable widgets for stars and individual reviews, you can develop a robust and maintainable review section that significantly enhances the user experience of your e-commerce application. This structured approach not only improves code readability but also makes it easier to scale and adapt to future design changes or feature additions.

Related Articles

May 14, 2026

Building a Multi-Event Countdown Timer Widget with Reminders, Notifications, Repeat, and Custom Labels in Flutter

Building a Multi-Event Countdown Timer Widget with Reminders, Notifications, Repeat, and Custom Labels in Flutter Countdown timers are essential in many applic

May 11, 2026

Unleashing Dynamic UIs: Flutter's Animation Prowess

Unleashing Dynamic UIs: Flutter's Animation Prowess for Slide & Scale Effects Flutter's declarative UI framework, combined with its powerful animation capabilit

May 11, 2026

Building a Product Detail Page Widget in Flutter with Related Items, Review Carousel, Promo Badges, and Quick Buy

Building a Product Detail Page Widget in Flutter with Related Items, Review Carousel, Promo Badges, and Quick Buy A well-designed Product Detail Page (PDP) is