// Dart Tips

Enums Are Not Just for Status —
They're a Superpower!

👤 Rohan Kumar Chaudhary
📅 2025
6 min read
🏷 Flutter · Dart · Clean Code · Architecture
"Stop writing boring enums. Since Dart 2.17, they're not just values — they're contracts."

Most Flutter/Dart developers use enums like this:

status.dart
// 😴 The boring, basic way most devs stop here enum Status { loading, success, error }

Basic switch cases. That's it. But since Dart 2.17, enhanced enums are absolute game-changers — you can add fields, constructors, methods, and getters, turning them into powerful, self-contained data models.

The Hidden Power

Enums in Dart can:

Instead of scattering magic strings, UI configs, switch cases, and duplicated logic all over your codebase — you design once and reuse everywhere.

Basic vs Enhanced Enum

before_after.dart
// ❌ Before — scattered logic, magic strings, duplicated UI code enum WorkoutType { running, cycling, swimming } String getLabel(WorkoutType type) { switch (type) { case WorkoutType.running: return 'Running'; case WorkoutType.cycling: return 'Cycling'; case WorkoutType.swimming: return 'Swimming'; } } Color getColor(WorkoutType type) { /* another switch... */ } IconData getIcon(WorkoutType type) { /* yet another switch... */ } // ✅ After — everything in one place, type-safe, zero duplication enum WorkoutType { running ('Running', 'km', Colors.orange, Icons.directions_run), cycling ('Cycling', 'km', Colors.blue, Icons.directions_bike), swimming('Swimming', 'm', Colors.cyan, Icons.pool); const WorkoutType(this.label, this.unit, this.color, this.icon); final String label; final String unit; final Color color; final IconData icon; }

Real-World Example — Health & Fitness App

This pattern shines in health, finance, and any data-heavy app. Here's a full example from a real fitness feature, similar to what's used in Zeno: Between Beats:

workout_type.dart
import 'package:flutter/material.dart'; enum WorkoutType { running ('Running', 'km', Color(0xFFFF6B35), Icons.directions_run), cycling ('Cycling', 'km', Color(0xFF4FC3F7), Icons.directions_bike), swimming('Swimming', 'm', Color(0xFF00E5A0), Icons.pool), yoga ('Yoga', 'min', Color(0xFFB39DDB), Icons.self_improvement), hiit ('HIIT', 'min', Color(0xFFFF5370), Icons.flash_on); const WorkoutType( this.label, this.unit, this.color, this.icon, ); final String label; final String unit; final Color color; final IconData icon; // ── Getters ────────────────────────────── Color get backgroundColor => color.withOpacity(0.12); bool get isCardio => this == WorkoutType.running || this == WorkoutType.cycling || this == WorkoutType.swimming; String get formattedUnit => '($unit)'; // ── Methods ─────────────────────────────── Widget getIconWidget({double size = 24}) => Icon( icon, color: color, size: size, ); String formatValue(double value) => '${value.toStringAsFixed(1)} $unit'; }

Using It in the UI

Now your UI code is clean, consistent, and impossible to break with a wrong string:

workout_card.dart
// Build a list of workout type chips — zero switch cases needed Wrap( spacing: 8, children: WorkoutType.values.map((type) { return Chip( avatar: type.getIconWidget(size: 18), label: Text(type.label), backgroundColor: type.backgroundColor, labelStyle: TextStyle(color: type.color), ); }).toList(), ) // Display a formatted value with the correct unit Text(WorkoutType.running.formatValue(5.4)) // → "5.4 km" // Check category without any string comparison if (WorkoutType.yoga.isCardio) { /* false — type-safe! */ }

More Patterns — Beyond Workout Types

This same pattern works everywhere in your app:

app_enums.dart
// API / network state with display logic enum ApiState<T> { idle ('Idle', false), loading('Loading', true ), success('Done', false), error ('Error', false); const ApiState(this.label, this.isLoading); final String label; final bool isLoading; } // Bottom nav tabs with route + icon in one place enum AppTab { home ('/home', Icons.home, 'Home'), activity('/activity', Icons.bar_chart, 'Activity'), profile ('/profile', Icons.person_outline, 'Profile'); const AppTab(this.route, this.icon, this.label); final String route; final IconData icon; final String label; }

Why This Is a Superpower

Why This Matters in Real Apps

When enums own their labels, units, colors, and behavior — your app becomes:

Enums aren't just values. They're contracts.
Stop writing boring enums. Level up your code today! 🚀
By Rohan Kumar Chaudhary | Flutter · iOS · Mobile Developer | Clean Code Advocate 🧼💙
Happy Coding! 💙
#Flutter #Dart #MobileDev #CleanCode #FlutterDev #EnhancedEnums #Dart2.17
Rohan Kumar Chaudhary
Rohan Kumar Chaudhary
Flutter · iOS · Mobile Developer