Kinda Code
Home/Flutter/Write a simple BMI Calculator with Flutter (Updated)

Write a simple BMI Calculator with Flutter (Updated)

Last updated: May 18, 2023

In this article, we’ll build a simple BMI (body mass index) calculator with Flutter from scratch.

This tutorial aims at people who are new to Flutter, so I’ll make it as simple as possible with the latest Flutter updates and features. We won’t learn old things or complicated things.

What you need to know first is the BMI formula:

BMI = weight (kg) / [height (m)]2

If you want to dig deeper about BMI, take a look at this article on Wikipedia.

Note: This article was recently updated to migrate to null safety and work well with Flutter 3 or newer

Prerequisites

To follow along with this tutorial, you need the following:

  • Flutter SDK installed on your computer
  • iOS Simulator or Android emulator installed
  • Flutter version 3 or newer
  • Know how to create a new Flutter project

If you haven’t set up Flutter yet, check this guide (Windows) or this guide (Mac).

Project Overview

Here’s how our app works at the end of this tutorial:

The BMI will be calculated as soon as the user presses the button. In addition to the BMI result showing up on the screen, there will be a simple message about the user’s body condition.

The Steps

If you want to see the final code right now, skip this section and jump to the next one.

1. In your terminal window, navigate to the place you would like your new Flutter application to be located and run the following command:

flutter create bmi_example

2. Start an iOS simulator or an Android emulator:

3. Navigate into the new project directory:

cd bmi_example

Then boost it up:

flutter run

4. Remove everything in your lib/main.dart and add this starter code:

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

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      // Remove the debug banner icon
      debugShowCheckedModeBanner: false,
      title: 'KindaCode.com',
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        // The later code will go here
        );
  }
}

Hot restart the app by pressing “Shift” + “R” and you will see this:

Building the UI

In this step, we will build the app’s UI and register the controllers for the text fields.

Modify the _HomePageState class like this:

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  // the controller for the text field associated with "height"
  final _heightController = TextEditingController();

  // the controller for the text field associated with "weight"
  final _weightController = TextEditingController();

  double? _bmi;
  // the message at the beginning
  String _message = 'Please enter your height an weight';

  // This function is triggered when the user pressess the "Calculate" button
  void _calculate() {}

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.deepOrange,
        body: Center(
          child: SizedBox(
            width: 320,
            child: Card(
              color: Colors.white,
              elevation: 10,
              child: Padding(
                padding: const EdgeInsets.all(20),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    TextField(
                      keyboardType:
                          const TextInputType.numberWithOptions(decimal: true),
                      decoration:
                          const InputDecoration(labelText: 'Height (m)'),
                      controller: _heightController,
                    ),
                    TextField(
                      keyboardType:
                          const TextInputType.numberWithOptions(decimal: true),
                      decoration: const InputDecoration(
                        labelText: 'Weight (kg)',
                      ),
                      controller: _weightController,
                    ),
                    ElevatedButton(
                      onPressed: _calculate,
                      child: const Text('Calculate'),
                    ),
                    const SizedBox(
                      height: 30,
                    ),
                    Text(
                      _bmi == null ? 'No Result' : _bmi!.toStringAsFixed(2),
                      style: const TextStyle(fontSize: 50),
                      textAlign: TextAlign.center,
                    ),
                    const SizedBox(
                      height: 20,
                    ),
                    Text(
                      _message,
                      textAlign: TextAlign.center,
                    )
                  ],
                ),
              ),
            ),
          ),
        ));
  }
}

Reload the app, and you will see this:

Writing The Logic Code

Our app now looks pretty good so far, but it does nothing. Let’s add the necessary logic to the _calculate function:

void _calculate() {
  final double? height = double.tryParse(_heightController.value.text);
  final double? weight = double.tryParse(_weightController.value.text);

  // Check if the inputs are valid
  if (height == null || height <= 0 || weight == null || weight <= 0) {
    setState(() {
      _message = "Your height and weigh must be positive numbers";
    });
    return;
  }

  setState(() {
    _bmi = weight / (height * height);
    if (_bmi! < 18.5) {
      _message = "You are underweight";
    } else if (_bmi! < 25) {
      _message = 'You body is fine';
    } else if (_bmi! < 30) {
      _message = 'You are overweight';
    } else {
      _message = 'You are obese';
    }
  });
}

Now hot restart the app and check it out:

The Final Code

Here’s the complete code that produces our BMI calculator:

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

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      // Remove the debug banner
      debugShowCheckedModeBanner: false,
      title: 'KindaCode.com',
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  // the controller for the text field associated with "height"
  final _heightController = TextEditingController();

  // the controller for the text field associated with "weight"
  final _weightController = TextEditingController();

  double? _bmi;
  // the message at the beginning
  String _message = 'Please enter your height an weight';

  // This function is triggered when the user pressess the "Calculate" button
  void _calculate() {
    final double? height = double.tryParse(_heightController.value.text);
    final double? weight = double.tryParse(_weightController.value.text);

    // Check if the inputs are valid
    if (height == null || height <= 0 || weight == null || weight <= 0) {
      setState(() {
        _message = "Your height and weigh must be positive numbers";
      });
      return;
    }

    setState(() {
      _bmi = weight / (height * height);
      if (_bmi! < 18.5) {
        _message = "You are underweight";
      } else if (_bmi! < 25) {
        _message = 'You body is fine';
      } else if (_bmi! < 30) {
        _message = 'You are overweight';
      } else {
        _message = 'You are obese';
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.deepOrange,
        body: Center(
          child: SizedBox(
            width: 320,
            child: Card(
              color: Colors.white,
              elevation: 10,
              child: Padding(
                padding: const EdgeInsets.all(20),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    TextField(
                      keyboardType:
                          const TextInputType.numberWithOptions(decimal: true),
                      decoration:
                          const InputDecoration(labelText: 'Height (m)'),
                      controller: _heightController,
                    ),
                    TextField(
                      keyboardType:
                          const TextInputType.numberWithOptions(decimal: true),
                      decoration: const InputDecoration(
                        labelText: 'Weight (kg)',
                      ),
                      controller: _weightController,
                    ),
                    ElevatedButton(
                      onPressed: _calculate,
                      child: const Text('Calculate'),
                    ),
                    const SizedBox(
                      height: 30,
                    ),
                    Text(
                      _bmi == null ? 'No Result' : _bmi!.toStringAsFixed(2),
                      style: const TextStyle(fontSize: 50),
                      textAlign: TextAlign.center,
                    ),
                    const SizedBox(
                      height: 20,
                    ),
                    Text(
                      _message,
                      textAlign: TextAlign.center,
                    )
                  ],
                ),
              ),
            ),
          ),
        ));
  }
}

Conclusion

Congratulation. You have made a Flutter application. While this is only a simple application, it is a great starting point for working through more complex and difficult projects. If you’d like to explore more about Flutter, take a look at the following articles:

You can also check out our Flutter topic page or Dart topic page for the latest tutorials and examples.