Make a BMI Calculator App with Flutter

What This App Does

A BMI Calculator app serves a specific need in today's mobile-first world. Building one with Flutter means you ship to iOS, Android, and the web from a single codebase, cutting development time dramatically while keeping a native-quality experience.

Main Features

Feature Why It Matters
Height & Weight Input Sliders or text fields for metric/imperial units with instant validation
BMI Calculation Engine Formula: weight (kg) / height (m)^2, categorised into underweight, normal, overweight, obese
History & Trends Store past results locally and show a chart of BMI over time

How to Make a BMI Calculator App with Flutter

Height & Weight Input

class InputCard extends StatelessWidget {
  final String label;
  final double value;
  final double min, max;
  final String unit;
  final ValueChanged onChanged;

  const InputCard({super.key, required this.label, required this.value,
    required this.min, required this.max, required this.unit,
    required this.onChanged});

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(label, style: Theme.of(context).textTheme.titleMedium),
            const SizedBox(height: 8),
            Row(
              children: [
                Expanded(
                  child: Slider(
                    value: value, min: min, max: max,
                    divisions: (max - min).round(),
                    label: value.toStringAsFixed(1),
                    onChanged: onChanged,
                  ),
                ),
                SizedBox(width: 72,
                  child: Text('${value.toStringAsFixed(1)} $unit',
                    textAlign: TextAlign.end,
                    style: Theme.of(context).textTheme.bodyLarge),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

BMI Calculation Engine

class BmiCalculator {
  static double calculate({required double weightKg, required double heightCm}) {
    final heightM = heightCm / 100;
    return weightKg / (heightM * heightM);
  }

  static ({String label, Color color, int riskLevel}) categorise(double bmi) {
    if (bmi < 18.5) return (label: 'Underweight', color: Colors.blue, riskLevel: 1);
    if (bmi < 25)   return (label: 'Normal', color: Colors.green, riskLevel: 0);
    if (bmi < 30)   return (label: 'Overweight', color: Colors.orange, riskLevel: 2);
    return (label: 'Obese', color: Colors.red, riskLevel: 3);
  }
}

History & Trends

class BmiRecord {
  final DateTime date; final double bmi;
  BmiRecord({required this.date, required this.bmi});
  Map toJson() => {'date': date.toIso8601String(), 'bmi': bmi};
  factory BmiRecord.fromJson(Map json) => BmiRecord(
    date: DateTime.parse(json['date']), bmi: (json['bmi'] as num).toDouble());
}

class BmiHistory {
  static const _key = 'bmi_history';
  static Future> load() async {
    final prefs = await SharedPreferences.getInstance();
    final raw = prefs.getString(_key);
    if (raw == null) return [];
    return (jsonDecode(raw) as List).map((e) => BmiRecord.fromJson(e)).toList();
  }
  static Future save(List records) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(_key, jsonEncode(records.map((r) => r.toJson()).toList()));
  }
}

Recommended Libraries

Package Purpose
flutter_form_builder Pre-built form fields and validators
shared_preferences Persist BMI history as JSON
fl_chart Trend line chart of past BMI records

UI & UX Suggestions

Use a teal primary, amber secondary, category colours colour palette to match the app's purpose. Keep the navigation simple — a bottom nav bar or a single-scroll layout works best for this type of app. Make sure every interaction provides haptic or visual feedback so the app feels responsive and polished.