Membuat Aplikasi BMI Calculator dengan Flutter

 Membuat Aplikasi BMI Calculator dengan Flutter



Flutter merupakan framework UI dari Google yang memungkinkan kita membangun aplikasi mobile dengan tampilan modern dan performa tinggi hanya dengan satu basis kode. Pada artikel ini, kita akan membuat aplikasi BMI Calculator sederhana menggunakan Flutter dengan Material 3.

Aplikasi ini dapat menghitung Body Mass Index (BMI) berdasarkan:

  • Jenis kelamin

  • Umur

  • Tinggi badan

  • Berat badan

Hasil perhitungan akan menampilkan kategori BMI lengkap dengan indikator visual.

Apa itu BMI?

Body Mass Index (BMI) adalah nilai yang digunakan untuk mengetahui apakah berat badan seseorang tergolong:

  • Berat rendah

  • Normal

  • Berat berlebih

  • Obesitas

Rumus BMI:

BMI = berat badan (kg) / (tinggi badan (m))²

Fitur Aplikasi

Aplikasi BMI Calculator yang kita buat memiliki fitur berikut:

  • Input jenis kelamin (ChoiceChip)

  • Input umur

  • Input tinggi badan (cm)

  • Input berat badan (kg)

  • Perhitungan BMI otomatis

  • Kategori BMI dengan warna indikator

  • Progress bar visual

  • Tombol reset (Cek Ulang)

  • Tampilan modern dengan gradient background dan Material 3


Struktur Aplikasi

Aplikasi terdiri dari dua widget utama:

  1. BMICalculatorApp → Root aplikasi

  2. BMICalculatorPage → Halaman utama dengan StatefulWidget


Inisialisasi Aplikasi

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

Kode ini berfungsi sebagai titik awal aplikasi Flutter.


Konfigurasi MaterialApp

MaterialApp( debugShowCheckedModeBanner: false, title: 'BMI Calculator', theme: ThemeData( useMaterial3: true, fontFamily: 'Roboto', ), home: const BMICalculatorPage(), );
  • Menggunakan Material 3

  • Menghilangkan debug banner

  • Menentukan halaman utama aplikasi


Input Data Pengguna

Aplikasi menggunakan TextEditingController untuk mengambil input:

  • Umur

  • Tinggi badan

  • Berat badan

final heightController = TextEditingController(); final weightController = TextEditingController(); final ageController = TextEditingController();

Pemilihan Jenis Kelamin

Pemilihan gender menggunakan ChoiceChip:

ChoiceChip( label: const Text('Laki-laki'), selected: gender == 'Laki-laki', onSelected: (_) => setState(() => gender = 'Laki-laki'), ),

Komponen ini membuat UI lebih interaktif dan modern.


Logika Perhitungan BMI

final result = weight / ((height / 100) * (height / 100));

Kategori BMI ditentukan dengan kondisi:

  • < 18.5 → Berat Rendah

  • 18.5 – 24.9 → Normal

  • 25 – 29.9 → Berat Berlebih

  • ≥ 30 → Obesitas

Setiap kategori memiliki warna berbeda untuk memperjelas hasil.


Menampilkan Hasil

Jika BMI sudah dihitung, aplikasi akan menampilkan:

  • Kategori BMI

  • Warna indikator

  • Progress bar BMI

  • Informasi umur, tinggi, dan berat badan

LinearProgressIndicator( value: (bmi / 40).clamp(0, 1), color: categoryColor, )

Reset Perhitungan

Pengguna bisa menghitung ulang dengan tombol Cek Ulang:

void reset() { setState(() { bmi = 0; heightController.clear(); weightController.clear(); ageController.clear(); }); }

Tampilan UI

Aplikasi menggunakan:

  • Gradient background

  • Card dengan rounded corner

  • Icon kesehatan

  • Layout responsif (ConstrainedBox)

Semua ini membuat tampilan terlihat profesional dan nyaman digunakan.


ini codenya:

import 'package:flutter/material.dart';

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

class BMICalculatorApp extends StatelessWidget {
  const BMICalculatorApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'BMI Calculator',
      theme: ThemeData(
        useMaterial3: true,
        fontFamily: 'Roboto',
      ),
      home: const BMICalculatorPage(),
    );
  }
}

class BMICalculatorPage extends StatefulWidget {
  const BMICalculatorPage({super.key});

  @override
  State<BMICalculatorPage> createState() => _BMICalculatorPageState();
}

class _BMICalculatorPageState extends State<BMICalculatorPage> {
  final heightController = TextEditingController();
  final weightController = TextEditingController();
  final ageController = TextEditingController(); // 👉 UMUR

  String gender = 'Laki-laki';
  double bmi = 0;
  String category = '';
  Color categoryColor = Colors.red;

  void calculateBMI() {
    final height = double.tryParse(heightController.text) ?? 0;
    final weight = double.tryParse(weightController.text) ?? 0;
    final age = int.tryParse(ageController.text) ?? 0;

    if (height <= 0 || weight <= 0 || age <= 0) return;

    final result = weight / ((height / 100) * (height / 100));

    String cat;
    Color color;

    if (result < 18.5) {
      cat = 'Berat Rendah';
      color = Colors.red;
    } else if (result < 24.9) {
      cat = 'Normal';
      color = Colors.green;
    } else if (result < 29.9) {
      cat = 'Berat Berlebih';
      color = Colors.orange;
    } else {
      cat = 'Obesitas';
      color = Colors.red;
    }

    setState(() {
      bmi = result;
      category = cat;
      categoryColor = color;
    });
  }

  void reset() {
    setState(() {
      bmi = 0;
      heightController.clear();
      weightController.clear();
      ageController.clear();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        decoration: const BoxDecoration(
          gradient: LinearGradient(
            colors: [Color(0xFF0F2027), Color(0xFF2C5364)],
            begin: Alignment.topLeft,
            end: Alignment.bottomRight,
          ),
        ),
        child: Center(
          child: SingleChildScrollView(
            padding: const EdgeInsets.all(20),
            child: ConstrainedBox(
              constraints: const BoxConstraints(maxWidth: 500),
              child: Card(
                elevation: 12,
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(24),
                ),
                child: Padding(
                  padding: const EdgeInsets.all(24),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    children: [
                      const Icon(Icons.health_and_safety,
                          size: 60, color: Colors.blue),
                      const SizedBox(height: 10),
                      const Text(
                        'BMI Ca-Calculator',
                        textAlign: TextAlign.center,
                        style: TextStyle(
                          fontSize: 28,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                      const SizedBox(height: 20),

                      /// GENDER
                      Row(
                        children: [
                          Expanded(
                            child: ChoiceChip(
                              label: const Text('Laki-laki'),
                              selected: gender == 'Laki-laki',
                              onSelected: (_) =>
                                  setState(() => gender = 'Laki-laki'),
                            ),
                          ),
                          const SizedBox(width: 12),
                          Expanded(
                            child: ChoiceChip(
                              label: const Text('Perempuan'),
                              selected: gender == 'Perempuan',
                              onSelected: (_) =>
                                  setState(() => gender = 'Perempuan'),
                            ),
                          ),
                        ],
                      ),

                      const SizedBox(height: 24),

                      /// UMUR (BARU)
                      TextField(
                        controller: ageController,
                        keyboardType: TextInputType.number,
                        decoration: InputDecoration(
                          labelText: 'Umur (tahun)',
                          filled: true,
                          fillColor: Colors.grey.shade100,
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(14),
                            borderSide: BorderSide.none,
                          ),
                        ),
                      ),

                      const SizedBox(height: 16),

                      /// TINGGI
                      TextField(
                        controller: heightController,
                        keyboardType: TextInputType.number,
                        decoration: InputDecoration(
                          labelText: 'Tinggi Badan (cm)',
                          filled: true,
                          fillColor: Colors.grey.shade100,
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(14),
                            borderSide: BorderSide.none,
                          ),
                        ),
                      ),

                      const SizedBox(height: 16),

                      /// BERAT
                      TextField(
                        controller: weightController,
                        keyboardType: TextInputType.number,
                        decoration: InputDecoration(
                          labelText: 'Berat Badan (kg)',
                          filled: true,
                          fillColor: Colors.grey.shade100,
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(14),
                            borderSide: BorderSide.none,
                          ),
                        ),
                      ),

                      const SizedBox(height: 24),

                      ElevatedButton(
                        onPressed: calculateBMI,
                        style: ElevatedButton.styleFrom(
                          padding: const EdgeInsets.symmetric(vertical: 16),
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(14),
                          ),
                          backgroundColor: Colors.blue,
                        ),
                        child: const Text(
                          'Hitung BMI',
                          style: TextStyle(color: Colors.white),
                        ),
                      ),

                      /// HASIL
                      if (bmi > 0) ...[
                        const SizedBox(height: 30),
                        Card(
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(16),
                          ),
                          child: Padding(
                            padding: const EdgeInsets.all(16),
                            child: Column(
                              children: [
                                Text(
                                  'BMI untuk $gender, ${ageController.text} tahun',
                                  style: const TextStyle(
                                      fontWeight: FontWeight.bold),
                                ),
                                const SizedBox(height: 6),
                                Text(
                                  category,
                                  style: TextStyle(
                                    fontSize: 22,
                                    fontWeight: FontWeight.bold,
                                    color: categoryColor,
                                  ),
                                ),
                                const SizedBox(height: 12),
                                LinearProgressIndicator(
                                  value: (bmi / 40).clamp(0, 1),
                                  minHeight: 10,
                                  color: categoryColor,
                                  backgroundColor:
                                      Colors.grey.shade300,
                                ),
                                const SizedBox(height: 12),
                                Text(
                                  'TB ${heightController.text} cm | BB ${weightController.text} kg',
                                  style: const TextStyle(fontSize: 12),
                                ),
                                const SizedBox(height: 8),
                                const Text(
                                  'Utamakan hidup sehat dan perhatikan konsumsi harian',
                                  textAlign: TextAlign.center,
                                ),
                                TextButton(
                                  onPressed: reset,
                                  child: const Text('Cek Ulang'),
                                ),
                              ],
                            ),
                          ),
                        ),
                      ]
                    ],
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

ini link nya ...

Kesimpulan

Dengan Flutter, kita bisa membuat aplikasi kesehatan sederhana seperti BMI Calculator dengan cepat dan tampilan yang modern. Proyek ini cocok untuk:

  • Pemula Flutter

  • Tugas sekolah / kuliah

  • Portofolio aplikasi mobile

Ke depannya, aplikasi ini bisa dikembangkan dengan:

  • Riwayat BMI

  • Saran kesehatan

  • Grafik perkembangan BMI

  • Penyimpanan data lokal

Komentar

Postingan populer dari blog ini

Belajar Flutter Biar Gak Cupu: Bikin App Ada Foto + Tombol SnackBar

membuat aplikasi sederhana dengan konsep CRUD - ngawiflix

Membuat Aplikasi Flutter Daftar Film MCU dengan Navigasi & Layout responsif