Building a Custom Flutter Widget from Scratch
Tags: flutter, custom, widgets
Published: 2024-06-21 16:38:57

---
title: Building a Custom Flutter Widget from Scratch
published: true
description: Walk through the process of creating a reusable widget with unique functionality, animations, and interactions.
tags: #flutter, #custom, #widgets
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ov27p2j7nuo40r2d2fjr.png
# Use a ratio of 100:42 for best results.
# published_at: 2024-06-19 11:05 +0000
---



Flutter's magic lies in its extensive widget library. But what if you need a UI element that doesn't quite fit the mold? That's where custom widgets come in! Buckle up, Flutter developers, as we embark on a journey to build a custom widget from scratch.



**Why Custom Widgets?**

Custom widgets offer a treasure trove of benefits:

* **Reusability:** Write your widget once, use it everywhere! This saves code, promotes consistency, and streamlines development.
* **Encapsulation:** Package functionality and appearance into a neat unit, keeping your code clean and organized.
* **Customization:** Tailor your widget's behavior and appearance to precisely meet your needs.



**Let's Build a Star Rating Widget!**

Imagine a widget that displays a row of stars, allowing users to rate something. Here's how we'll break it down:

**1. Setting Up:**

Create a new Flutter project and a dedicated Dart file for your widget (e.g., custom_rating_bar.dart).
Import necessary packages like flutter and material.

**2. The CustomStarRating Class:**

Define a class named `CustomRatingBar` that extends `StatelessWidget`.

**3. Star Count and Rating Properties:**

Add properties to the `CustomRatingBar` class:
`starCount`: An integer representing the total number of stars.
`rating`: A double representing the current user rating (optional).
`filledColor`: Color representing the filled color for the star.
`unfilledColor`: Color representing the unfilled color for the star.

**4. Building the Stars:**

Override the build method of the `CustomRatingBar` class.
Use a Row widget to display the stars horizontally.
Loop through a list based on `starCount`.
Inside the loop, use an `Icon` for each star.
Customize the Icon displayed based on the current rating (filled star for selected, unfilled star for unselected).

**5. Handling User Interaction:**

Set the `onTap` callback of the `GestureDetector` to update the `rating` property.
Consider emitting an event (using a `ValueNotifier` or similar) to notify parent widgets about rating changes.

**6. Adding Flair (Optional):**

Style your stars using `Icon` properties like color and size.
Implement custom animations for star selection using AnimatedIcon.



**Putting it All Together:**

With all the pieces in place, use the `CustomRatingBar` widget in your app's layout:

```dart
CustomRatingBar(starCount: 5, rating: 1.0,
                filledColor: Colors.amber,
                unfilledColor: Colors.grey,
                onRatingChanged: () {})
```

`custom_rating_bar.dart`

```dart
import 'package:flutter/material.dart';

class CustomRatingBar extends StatefulWidget {
  final double rating;
  final int starCount;
  final Function onRatingChanged;
  final Color filledColor;
  final Color unfilledColor;

  const CustomRatingBar({
    super.key,
    required this.rating,
    required this.starCount,
    required this.onRatingChanged,
    required this.unfilledColor,
    required this.filledColor,
  });

  @override
  State<CustomRatingBar> createState() => _CustomRatingBarState();
}

class _CustomRatingBarState extends State<CustomRatingBar> {
  double _currentRating = 0.0;

  @override
  void initState() {
    super.initState();
    _currentRating = widget.rating - 1;
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      children: List.generate(
        widget.starCount,
        (index) => GestureDetector(
          onTap: () => _onStarTap(index.toDouble()),
          child: Icon(
            Icons.star,
            size: 30.0,
            color: _getColor(index),
          ),
        ),
      ),
    );
  }

  Color _getColor(int index) {
    if (index <= _currentRating) {
      return widget.filledColor;
    } else {
      return widget.unfilledColor;
    }
  }

  void _onStarTap(double newRating) {
    if (_currentRating == newRating) {
      newRating--;
    }
    setState(() {
      _currentRating = newRating;
      // widget.onRatingChanged(newRating);
    });
  }
}
```



**Conclusion**


This blog demonstrates a basic implementation of a custom rating bar in Flutter. It offers features like:

**Star Count:** You can easily adjust the number of stars displayed.
**Rating:** Users can tap on stars to provide their rating.
**Colors:** Define the desired colors and icons for filled, empty, and half-filled states (if applicable).

**Further Enhancement Scopes**

* **Animated Selection:** The selected stars smoothly animate with a scaling effect.
* **Half Rating Support:** Modify the function to include logic for displaying half-filled stars.

[GitHub Code](https://github.com/harsh8088/flutter_samples/blob/master/lib/custom/custom_rating_bar.dart) 

Happy Coding!!! 🧑🏻‍💻