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:
- Make a “Scroll Back To Top” button
- Flutter: Making a Tic Tac Toe Game from Scratch
- Flutter: Making a Length Converter from Scratch
- Flutter: Create a Password Strength Checker from Scratch
- How to create Circle Charts (Pie Charts) in Flutter
- Flutter and Firestore Database: CRUD example (null safety)
You can also check out our Flutter topic page or Dart topic page for the latest tutorials and examples.