arch-atlas

Best seller item done

Presentation (Building the UI)

10:13

Summary

In this lesson, the instructor completes the UI for the "Best Seller" list item by building the rating component. The primary focus is on constructing the BookRating widget using a Row to align a star icon and text elements. A significant portion of the lesson covers layout constraints, specifically how to use the Expanded widget to force a parent Column to take up all available horizontal space so that a Spacer inside a child Row functions correctly. Finally, the instructor demonstrates good structural practices by extracting the BookRating widget into its own dedicated file to keep the code organized and maintainable.

Key Ideas

  • BookRating widget encapsulates the star icon, rating score, and rating count within a Row.
  • FontAwesomeIcons.solidStar is preferred over the default Material star icon for a sharper visual appearance.
  • Spacer widget is used within a Row to push the price and rating apart, but it requires the parent to have a bounded or expanded width to function.
  • Expanded widget must wrap the parent Column to grant it the maximum available width, which in turn allows the child Row to expand properly.
  • TextStyle.copyWith() allows for quick inline overrides of predefined styles, such as changing the color or font weight, without creating a new style from scratch.
  • Extracting smaller components like BookRating into separate files prevents a single UI file from becoming bloated and hard to read.

Code Snippets

The BookRating widget extracted into its own filedart
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import '../../../../core/utils/styles.dart';

class BookRating extends StatelessWidget {
  const BookRating({super.key});

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        const Icon(
          FontAwesomeIcons.solidStar,
          color: Color(0xffFFDD4F),
        ),
        const SizedBox(
          width: 6.3,
        ),
        const Text(
          '4.8',
          style: Styles.textStyle16,
        ),
        const SizedBox(
          width: 5,
        ),
        Text(
          '(245)',
          style: Styles.textStyle14.copyWith(
            color: const Color(0xff707070),
          ),
        ),
      ],
    );
  }
}
Using Expanded and Spacer to layout the price and rating in the Best Seller itemdart
Expanded(
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      // ... title and author text widgets
      Row(
        children: [
          Text(
            '19.99 €',
            style: Styles.textStyle20.copyWith(
              fontWeight: FontWeight.bold,
            ),
          ),
          const Spacer(),
          const BookRating(),
        ],
      ),
    ],
  ),
),

My Notes

The main gotcha in this lesson is the nested Row -> Column -> Row layout issue. The instructor correctly demonstrates that a nested Row won't automatically expand to fill horizontal space if its parent Column doesn't do so first.

  • Spacer vs MainAxisAlignment: The instructor uses a Spacer() to push the price to the left and the rating to the right. [Editor's note] An equally valid and slightly cleaner approach is to use mainAxisAlignment: MainAxisAlignment.spaceBetween on the Row itself, which eliminates the need for the extra Spacer widget.
  • Mock Data: The ratings (4.8) and counts (245) are hardcoded for now. [Editor's note] In a real Clean Architecture setup, these values will eventually be passed down from the domain entity via the constructor of BookRating.