Why we need enum in Flutter

The enum is the short form of enumerated type. Therefore, enum is just like any other data type.

Moreover, enum is a set of named values that we call elements or enumerators.

As a result, we can use enum “Type” value where we want them. And, enumerator names act as constant values.

In Natural Language the word enumeration means an action of mentioning names one by one.

In any Dart and Flutter, we write enum the following way.

enum Names {
John,
Json,
}

Now, we can access the enumerator values as follows.

Names.John
Names.Json

However, the question remains, why we need enum?

We have seen static constant class variables before. Does it not look same?

The answer is no. We cannot do that.

The enums are useful when the method parameter can only take one value out of a small set of possible values.

Suppose we have two types of robots. One robot thinks. And the other robot works.

Consequently, we can create two types of Robots.

void main() {
  
  Robot worker = Robot(robotType: RobotType.worker);
  Robot thinker = Robot(robotType: RobotType.thinker);
  
  if(worker.robotType == RobotType.worker) {
    print('My robot has just cleaned the room.');
  } else {
    print('My robot has not done anything.');
  } // My robot has just cleaned the room.
  
  if(thinker.robotType == RobotType.thinker) {
    print('My robot has just solved a Mathematical problem.');
  } else {
    print('My robot has not done anything.');
  } // My robot has just solved a Mathematical problem.
    
}

class Robot {
  
  RobotType? robotType;
  
  Robot({this.robotType});  
  
}

enum RobotType {
  worker,
  thinker,  
}

The above code does make sense. Why? Because we wanted to create two types of Robot.

On the contrary, when we use static constant class variables instead of enums, the perspective completely changes.

Not only that, it no longer remains meaningful as before.

Consider the code below where we use static constant class variables.

void main() {  
  
  Robot worker = Robot(name: RobotType.worker);
  Robot thinker = Robot(name: RobotType.thinker);
  
  if(worker.name == RobotType.worker) {
    print('My robot has just cleaned the room.');
  } else {
    print('My robot has not done anything.');
  } // My robot has just cleaned the room.
  
  if(thinker.name == RobotType.thinker) {
    print('My robot has just solved a Mathematical problem.');
  } else {
    print('My robot has not done anything.');
  } // My robot has just solved a Mathematical problem.
    
}

class Robot {
  
  String? name;
  
  Robot({this.name});  
  
}

class RobotType {
  static const worker = 'Worker';
  static const thinker = 'Thinker';  
}

Although it serves our purpose, yet it is not meaningful as before.

Ask yourself one simple question. From name can you guess the type of a person?

But when you precisely define the type, you can predict the output. That is also true when we apply the same concept.

Let us see how enum changes the code in Flutter.

How to use enum in Flutter?

It will be clearer, if we see the images firstly. Let us explain what we are going to achieve.

We have created two Container Widgets of the same color. Yellow.

Why we need enum in Flutter_ first example
Why we need enum in Flutter_ first example

As we press the first Container, the color changes to red. However, the second container remains yellow.

Why we need enum in Flutter_ second example
Why we need enum in Flutter_ second example

Next, when we press the second Container, it becomes red this time. But the first becomes yellow again.

We can achieve this state change with the help of a Stateful Widget. In addition we need setState() method, where we can call another method that changes the color.

As a consequence, we can pass an integer through that method. If the number is 1, the first Container changes color.

If the number is 2, the second Container changes the color.

import 'package:flutter/material.dart';

// this is a new branch enum and color change

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

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Happiness Calculator'),
    );
  }
}

const inactiveColor = Colors.amber;
const activeColor = Colors.red;

class MyHomePage extends StatefulWidget {
  const MyHomePage({
    Key? key,
    required this.title,
  }) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Color firstContainerColor = inactiveColor;
  Color secondContainerColor = inactiveColor;
  void _changeColor(int container) {
    if (container == 1) {
      firstContainerColor = activeColor;
      secondContainerColor = inactiveColor;
    } else {
      firstContainerColor = inactiveColor;
    }
    if (container == 2) {
      secondContainerColor = activeColor;
      firstContainerColor = inactiveColor;
    } else {
      secondContainerColor = inactiveColor;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Row(
              children: [
                Expanded(
                  child: Padding(
                    padding: const EdgeInsets.all(18.0),
                    child: GestureDetector(
                      onTap: () {
                        setState(() {
                          _changeColor(1);
                        });
                      },
                      child: Container(
                        alignment: Alignment.center,
                        color: firstContainerColor,
                        width: 250.0,
                        height: 250.0,
                        child: const Text('Press Me'),
                      ),
                    ),
                  ),
                ),
                Expanded(
                  child: Padding(
                    padding: const EdgeInsets.all(18.0),
                    child: GestureDetector(
                      onTap: () {
                        setState(() {
                          _changeColor(2);
                        });
                      },
                      child: Container(
                        alignment: Alignment.center,
                        color: secondContainerColor,
                        width: 250.0,
                        height: 250.0,
                        child: const Text('Press Me'),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

By changing two integer variables we can easily do this. However, when someone else will read this code, what will happen?

It will not be clear from our code snippet. Right? We have to explain the whole process in great detail

Instead of that, we can use enum. Which is self explanatory. Even we do not have to add any comment why we are doing this.

Why we need enum?

Exactly for this reason, we need enum. It makes our code more readable. In addition, it will make our code more self explanatory.

Therefore, we will rewrite our code, this way.

import 'package:flutter/material.dart';

// this is a new branch enum and color change

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

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Happiness Calculator'),
    );
  }
}

//TODO: we will use enum in this branch

enum ContainerColor {
  first,
  second,
}

const inactiveColor = Colors.amber;
const activeColor = Colors.red;

class MyHomePage extends StatefulWidget {
  const MyHomePage({
    Key? key,
    required this.title,
  }) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Color firstContainerColor = inactiveColor;
  Color secondContainerColor = inactiveColor;
  void _changeColor(ContainerColor selectedContainer) {
    if (selectedContainer == ContainerColor.first) {
      firstContainerColor = activeColor;
      secondContainerColor = inactiveColor;
    } else {
      firstContainerColor = inactiveColor;
    }
    if (selectedContainer == ContainerColor.second) {
      secondContainerColor = activeColor;
      firstContainerColor = inactiveColor;
    } else {
      secondContainerColor = inactiveColor;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Row(
              children: [
                Expanded(
                  child: Padding(
                    padding: const EdgeInsets.all(18.0),
                    child: GestureDetector(
                      onTap: () {
                        setState(() {
                          _changeColor(ContainerColor.first);
                        });
                      },
                      child: Container(
                        alignment: Alignment.center,
                        color: firstContainerColor,
                        width: 250.0,
                        height: 250.0,
                        child: const Text('Press Me'),
                      ),
                    ),
                  ),
                ),
                Expanded(
                  child: Padding(
                    padding: const EdgeInsets.all(18.0),
                    child: GestureDetector(
                      onTap: () {
                        setState(() {
                          _changeColor(ContainerColor.second);
                        });
                      },
                      child: Container(
                        alignment: Alignment.center,
                        color: secondContainerColor,
                        width: 250.0,
                        height: 250.0,
                        child: const Text('Press Me'),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

In the above code, we created two separate Container Color type by a set of two constant values.

enum ContainerColor {
  first,
  second,
}

As a result, now it becomes clear. We know, when we should use the first Container color, and when we should use the second Container color.

We get the same result. But this time, we do not have to explain why we’re doing this.

What Next?

Books at Leanpub

Books in Apress

My books at Amazon

Courses at Educative

GitHub repository

Technical blog

Twitter

Comments

7 responses to “Why we need enum in Flutter”

  1. […] In the previous section, we have learned what is enum in Dart and Flutter. […]

  2. […] have learned how to use enum. After that, we have used ternary operator to reduce the code […]

  3. […] we have discussed enum before. Secondly, we have reduced the code size by using the ternary operator. And finally, we have […]

  4. […] building this Flutter App, we have learned a few key concepts, such as enum, and ternary […]

  5. […] we have learned how to use enum. Secondly, we have learned ternary operator. Thirdly, we have grasped how to customize the Slider […]

  6. […] In the above code, we have many instance variables. Two of them of the enum type. We have discussed enum earlier. If you are a beginner, please read that section. […]

  7. […] In the previous section, we have learned what is enum in Dart and Flutter. […]

Leave a Reply