Flutter – Customizable Ratings bar

15 Feb, 2021
Rating Bar as the name suggests is used to rate content inside the application. More or less all applications use them either to gate user feedback on their application or to get a rating for content hosted by the application. Applications like IMDB use them to rate movies and Television series where apps like and Uber use them to get feedback on their services from the customer.
In this article we will build a simple app with the following features:
A horizontal Rating bar
A switch to make all rating bars above go right to left
A switch to make the rating bars vertical
Three different modes to change the Icon of the first rating bar
To build the above application follow the below steps:
Add the dependency to the pubspec.yaml file
Import the dependency to the main.dart file
Use the StatefulWidget to give structure to the application
Add the vertical rating bar
Add switch to change the alignment of the rating bars from right to left (RTL)
Add a switch to change the alignment of the rating bar from horizontal to vertical
Add 3 different modes that change the UI Icons.
To add the dependency to the pubspec.yaml file the following image can be followed:
To import the flutter_rating_bar dependency to the main.dart file, use the following:
import 'package:flutter_rating_bar/flutter_rating_bar.dart';

A StatefulWidget can be used to give the app an appbar and a body to hold content as shown below:
Dart
class MyApp extends StatefulWidget {  @override  _MyAppState createState() => _MyAppState();}  class _MyAppState extends State<MyApp> {  var _ratingController = TextEditingController();  double _rating;  int _ratingBarMode = 1;  bool _isRTLMode = false;  bool _isVertical = false;  IconData _selectedIcon;    @override  void initState() {    _ratingController.text = "3.0";    super.initState();  }    @override  Widget build(BuildContext context) {    return MaterialApp(      debugShowCheckedModeBanner: false,      theme: ThemeData(        primarySwatch: Colors.green,        appBarTheme: AppBarTheme(          textTheme: TextTheme(            title: Theme.of(context).textTheme.title.copyWith(              color: Colors.white,            ),          ),        ),      ),
A simple rating bar can be called upon from the flutter_rating_bar package by calling the RatingBar widget as shown below:
Dart
RatingBar(   initialRating: 3,   minRating: 1,   direction: Axis.horizontal,   allowHalfRating: true,   itemCount: 5,   itemPadding: EdgeInsets.symmetric(horizontal: 4.0),   itemBuilder: (context, _) => Icon(     Icons.star,     color: Colors.amber,   ),   onRatingUpdate: (rating) {     print(rating);   },);
At this stage, we will add a switch that can change the alignment of the rating bar from left to right, to right to left. It can be done by using the MainAxisAlignment as MainAxisAlignment.center and calling the _isRTL mode as shown below:
Dart
mainAxisAlignment: MainAxisAlignment.center,                   children: <Widget>[                     Text(                       'Switch to RTL Mode',                       style: TextStyle(                         fontWeight: FontWeight.w300,                       ),                     ),                     Switch(                       value: _isRTLMode,                       onChanged: (value) {                         setState(() {                           _isRTLMode = value;                         });                       },
At this stage, we will add a switch that can change the alignment of the rating bar from left to right, to right to left. It can be done by using the MainAxisAlignment as MainAxisAlignment.center and calling the _isVertical mode as shown below:
Dart
mainAxisAlignment: MainAxisAlignment.center,                   children: <Widget>[                     Text(                       'Switch to Vertical Bar',                       style: TextStyle(                         fontWeight: FontWeight.w300,                       ),                     ),                     Switch(                       value: _isVertical,                       onChanged: (value) {                         setState(() {                           _isVertical = value;                         });                       },                       activeColor: Colors.amber,                     ),                   ],                 ),
In this application, we will be adding 3 Mode and on the selection of each mode the rating bar Icon will change. We will be using the switch() function to assign the cases to modes and assign icons to the same as shown below:
Dart
Widget _ratingBar(int mode) {   switch (mode) {     case 1:       return RatingBar(         initialRating: 2,         minRating: 1,         direction: _isVertical ? Axis.vertical : Axis.horizontal,         allowHalfRating: true,         unratedColor: Colors.amber.withAlpha(50),         itemCount: 5,         itemSize: 50.0,         itemPadding: EdgeInsets.symmetric(horizontal: 4.0),         itemBuilder: (context, _) => Icon(           _selectedIcon ?? Icons.star,           color: Colors.amber,         ),         onRatingUpdate: (rating) {           setState(() {             _rating = rating;           });         },       );     case 2:       return RatingBar(         initialRating: 3,         direction: _isVertical ? Axis.vertical : Axis.horizontal,         allowHalfRating: true,         itemCount: 5,         ratingWidget: RatingWidget(           full: _image('assets/heart.png'),           half: _image('assets/heart_half.png'),           empty: _image('assets/heart_border.png'),         ),         itemPadding: EdgeInsets.symmetric(horizontal: 4.0),         onRatingUpdate: (rating) {           setState(() {             _rating = rating;           });         },       );     case 3:       return RatingBar(         initialRating: 3,         direction: _isVertical ? Axis.vertical : Axis.horizontal,         itemCount: 5,         itemPadding: EdgeInsets.symmetric(horizontal: 4.0),         itemBuilder: (context, index) {           switch (index) {             case 0:               return Icon(                 Icons.sentiment_very_dissatisfied,                 color: Colors.red,               );             case 1:               return Icon(                 Icons.sentiment_dissatisfied,                 color: Colors.redAccent,               );             case 2:               return Icon(                 Icons.sentiment_neutral,                 color: Colors.amber,               );             case 3:               return Icon(                 Icons.sentiment_satisfied,                 color: Colors.lightGreen,               );             case 4:               return Icon(                 Icons.sentiment_very_satisfied,                 color: Colors.green,               );             default:               return Container();           }         },         onRatingUpdate: (rating) {           setState(() {             _rating = rating;           });         },       );     default:       return Container();   } }
Complete Source Code:
Dart
import 'package:flutter/material.dart';import 'package:flutter_rating_bar/flutter_rating_bar.dart';  void main() => runApp(MyApp());  class MyApp extends StatefulWidget {  @override  _MyAppState createState() => _MyAppState();}  class _MyAppState extends State<MyApp> {  var _ratingController = TextEditingController();  double _rating;  int _ratingBarMode = 1;  bool _isRTLMode = false;  bool _isVertical = false;  IconData _selectedIcon;    @override  void initState() {    _ratingController.text = "3.0";    super.initState();  }    @override  Widget build(BuildContext context) {    return MaterialApp(      debugShowCheckedModeBanner: false,      theme: ThemeData(        primarySwatch: Colors.green,        appBarTheme: AppBarTheme(          textTheme: TextTheme(            title: Theme.of(context).textTheme.title.copyWith(              color: Colors.white,            ),          ),        ),      ),      home: Builder(        builder: (context) => Scaffold(          appBar: AppBar(            title: Text('GeeksForGeeks'),            backgroundColor: Colors.green,          ),          body: Directionality(            textDirection: _isRTLMode ? TextDirection.rtl : TextDirection.ltr,            child: SingleChildScrollView(              child: Column(                crossAxisAlignment: CrossAxisAlignment.center,                mainAxisSize: MainAxisSize.min,                children: <Widget>[                  SizedBox(                    height: 40.0,                  ),                  _heading('Rating Bar'),                  _ratingBar(_ratingBarMode),                  SizedBox(                    height: 20.0,                  ),                  _rating != null                      ? Text(                    "Rating: $_rating",                    style: TextStyle(fontWeight: FontWeight.bold),                  )                      : Container(),                  Row(                    children: [                      _radio(1),                      _radio(2),                      _radio(3),                    ],                  ),                  Row(                    mainAxisAlignment: MainAxisAlignment.center,                    children: <Widget>[                      Text(                        'Switch to Vertical Bar',                        style: TextStyle(                          fontWeight: FontWeight.w300,                        ),                      ),                      Switch(                        value: _isVertical,                        onChanged: (value) {                          setState(() {                            _isVertical = value;                          });                        },                        activeColor: Colors.amber,                      ),                    ],                  ),                  Row(                    mainAxisAlignment: MainAxisAlignment.center,                    children: <Widget>[                      Text(                        'Switch to RTL Mode',                        style: TextStyle(                          fontWeight: FontWeight.w300,                        ),                      ),                      Switch(                        value: _isRTLMode,                        onChanged: (value) {                          setState(() {                            _isRTLMode = value;                          });                        },                        activeColor: Colors.amber,                      ),                    ],                  ),                ],              ),            ),          ),        ),      ),    );  }    Widget _radio(int value) {    return Expanded(      child: RadioListTile(        value: value,        groupValue: _ratingBarMode,        dense: true,        title: Text(          'Mode $value',          style: TextStyle(            fontWeight: FontWeight.w300,            fontSize: 12.0,          ),        ),        onChanged: (value) {          setState(() {            _ratingBarMode = value;          });        },      ),    );  }    Widget _ratingBar(int mode) {    switch (mode) {      case 1:        return RatingBar(          initialRating: 2,          minRating: 1,          direction: _isVertical ? Axis.vertical : Axis.horizontal,          allowHalfRating: true,          unratedColor: Colors.amber.withAlpha(50),          itemCount: 5,          itemSize: 50.0,          itemPadding: EdgeInsets.symmetric(horizontal: 4.0),          itemBuilder: (context, _) => Icon(            _selectedIcon ?? Icons.star,            color: Colors.amber,          ),          onRatingUpdate: (rating) {            setState(() {              _rating = rating;            });          },        );      case 2:        return RatingBar(          initialRating: 3,          direction: _isVertical ? Axis.vertical : Axis.horizontal,          allowHalfRating: true,          itemCount: 5,          ratingWidget: RatingWidget(            full: _image('assets/heart.png'),            half: _image('assets/heart_half.png'),            empty: _image('assets/heart_border.png'),          ),          itemPadding: EdgeInsets.symmetric(horizontal: 4.0),          onRatingUpdate: (rating) {            setState(() {              _rating = rating;            });          },        );      case 3:        return RatingBar(          initialRating: 3,          direction: _isVertical ? Axis.vertical : Axis.horizontal,          itemCount: 5,          itemPadding: EdgeInsets.symmetric(horizontal: 4.0),          itemBuilder: (context, index) {            switch (index) {              case 0:                return Icon(                  Icons.sentiment_very_dissatisfied,                  color: Colors.red,                );              case 1:                return Icon(                  Icons.sentiment_dissatisfied,                  color: Colors.redAccent,                );              case 2:                return Icon(                  Icons.sentiment_neutral,                  color: Colors.amber,                );              case 3:                return Icon(                  Icons.sentiment_satisfied,                  color: Colors.lightGreen,                );              case 4:                return Icon(                  Icons.sentiment_very_satisfied,                  color: Colors.green,                );              default:                return Container();            }          },          onRatingUpdate: (rating) {            setState(() {              _rating = rating;            });          },        );      default:        return Container();    }  }    Widget _image(String asset) {    return Image.asset(      asset,      height: 30.0,      width: 30.0,      color: Colors.amber,    );  }    Widget _heading(String text) => Column(    children: [      Text(        text,        style: TextStyle(          fontWeight: FontWeight.w300,          fontSize: 24.0,        ),      ),      SizedBox(        height: 20.0,      ),    ],  );}
Output:
android
Flutter
Flutter UI-components
Dart
Flutter
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
ListView Class in Flutter
Flutter - Search Bar
Flutter - Dialogs
Flutter - FutureBuilder Widget
Flutter - Flexible Widget
Flutter Tutorial
Flutter - Search Bar
Flutter - Dialogs
Flutter - FutureBuilder Widget
Flutter - Flexible Widget