Panduan Lengkap Membuat Aplikasi Kalkulator BMI dengan Desain Menarik di Flutter.

 

📱 Pengenalan: Kalkulator BMI di Genggaman Anda

Halo para developer dan tech enthusiast! Pernahkah Anda ingin membuat aplikasi mobile yang berguna sekaligus menarik secara visual? Hari ini, saya akan membagikan pengalaman membuat aplikasi Kalkulator BMI (Body Mass Index) menggunakan Flutter dengan desain yang modern dan user-friendly.

BMI adalah indikator sederhana yang digunakan untuk mengkategorikan berat badan seseorang apakah termasuk underweight, normal, overweight, atau obese. Aplikasi ini tidak hanya berfungsi dengan baik, tetapi juga memiliki tampilan yang memukau!

🎯 Kenapa Flutter?

Flutter adalah framework Google untuk membangun aplikasi mobile yang bisa berjalan di iOS dan Android dengan satu codebase. Keunggulannya:

  • Fast Development: Hot reload untuk development yang cepat

  • Beautiful UI: Widget yang kaya dan customizable

  • Cross-platform: Satu kode untuk dua platform

  • Growing Community: Dokumentasi lengkap dan komunitas aktif

🚀 Langkah-langkah Membuat Aplikasi BMI

Langkah 1: Persiapan Environment

Sebelum mulai, pastikan Anda memiliki:

  1. Flutter SDK terinstal

  2. Editor (VS Code atau Android Studio)

  3. Emulator atau device fisik

Langkah 2: Membuat Proyek Baru

bash
flutter create bmi_calculator
cd bmi_calculator

Langkah 3: Struktur Kode Utama

Berikut adalah kode utama aplikasi BMI kita:

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

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

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

  
  State<BMICalculator> createState() => _BMICalculatorState();
}

class _BMICalculatorState extends State<BMICalculator> {
  double _height = 170;
  double _weight = 70;
  int _age = 25;
  String _gender = 'male';
  double _bmi = 0;
  String _category = '';
  String _advice = '';

  void _calculateBMI() {
    double heightInMeter = _height / 100;
    _bmi = _weight / (heightInMeter * heightInMeter);
    
    if (_bmi < 18.5) {
      _category = 'Underweight';
      _advice = 'Perbanyak asupan kalori dengan makanan bernutrisi';
    } else if (_bmi >= 18.5 && _bmi < 25) {
      _category = 'Normal';
      _advice = 'Pertahankan gaya hidup sehat Anda!';
    } else if (_bmi >= 25 && _bmi < 30) {
      _category = 'Overweight';
      _advice = 'Mulailah olahraga teratur dan diet seimbang';
    } else {
      _category = 'Obese';
      _advice = 'Konsultasikan dengan dokter untuk rencana penurunan berat badan';
    }
    
    setState(() {});
  }

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('BMI Calculator'),
          centerTitle: true,
        ),
        body: SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              children: [
                // Gender Selection
                Card(
                  child: Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: Column(
                      children: [
                        const Text('Gender', style: TextStyle(fontSize: 18)),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                          children: [
                            _buildGenderButton('Male', Icons.male, 'male'),
                            _buildGenderButton('Female', Icons.female, 'female'),
                          ],
                        ),
                      ],
                    ),
                  ),
                ),
                
                // Height Slider
                Card(
                  child: Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: Column(
                      children: [
                        Text('Height: ${_height.toInt()} cm'),
                        Slider(
                          value: _height,
                          min: 100,
                          max: 220,
                          onChanged: (value) {
                            setState(() {
                              _height = value;
                            });
                          },
                        ),
                      ],
                    ),
                  ),
                ),
                
                // Weight and Age
                Row(
                  children: [
                    Expanded(
                      child: Card(
                        child: Padding(
                          padding: const EdgeInsets.all(16.0),
                          child: Column(
                            children: [
                              const Text('Weight (kg)'),
                              Text('${_weight.toInt()}', style: TextStyle(fontSize: 24)),
                              Row(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: [
                                  IconButton(
                                    onPressed: () {
                                      setState(() {
                                        if (_weight > 30) _weight--;
                                      });
                                    },
                                    icon: const Icon(Icons.remove),
                                  ),
                                  IconButton(
                                    onPressed: () {
                                      setState(() {
                                        if (_weight < 200) _weight++;
                                      });
                                    },
                                    icon: const Icon(Icons.add),
                                  ),
                                ],
                              ),
                            ],
                          ),
                        ),
                      ),
                    ),
                    
                    Expanded(
                      child: Card(
                        child: Padding(
                          padding: const EdgeInsets.all(16.0),
                          child: Column(
                            children: [
                              const Text('Age'),
                              Text('$_age', style: TextStyle(fontSize: 24)),
                              Row(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: [
                                  IconButton(
                                    onPressed: () {
                                      setState(() {
                                        if (_age > 1) _age--;
                                      });
                                    },
                                    icon: const Icon(Icons.remove),
                                  ),
                                  IconButton(
                                    onPressed: () {
                                      setState(() {
                                        if (_age < 100) _age++;
                                      });
                                    },
                                    icon: const Icon(Icons.add),
                                  ),
                                ],
                              ),
                            ],
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
                
                // Calculate Button
                Container(
                  margin: const EdgeInsets.symmetric(vertical: 20),
                  width: double.infinity,
                  child: ElevatedButton(
                    onPressed: _calculateBMI,
                    style: ElevatedButton.styleFrom(
                      padding: const EdgeInsets.symmetric(vertical: 16),
                    ),
                    child: const Text('CALCULATE BMI', style: TextStyle(fontSize: 18)),
                  ),
                ),
                
                // Result Display
                if (_bmi > 0) _buildResultCard(),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildGenderButton(String label, IconData icon, String gender) {
    return ElevatedButton(
      onPressed: () {
        setState(() {
          _gender = gender;
        });
      },
      style: ElevatedButton.styleFrom(
        backgroundColor: _gender == gender ? Colors.blue : Colors.grey,
      ),
      child: Row(
        children: [
          Icon(icon),
          const SizedBox(width: 8),
          Text(label),
        ],
      ),
    );
  }

  Widget _buildResultCard() {
    Color color;
    if (_category == 'Underweight') {
      color = Colors.blue;
    } else if (_category == 'Normal') {
      color = Colors.green;
    } else if (_category == 'Overweight') {
      color = Colors.orange;
    } else {
      color = Colors.red;
    }
    
    return Card(
      color: color.withOpacity(0.1),
      child: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          children: [
            Text('Your BMI', style: TextStyle(fontSize: 20)),
            Text(_bmi.toStringAsFixed(1), 
                style: TextStyle(fontSize: 48, fontWeight: FontWeight.bold)),
            Text(_category, style: TextStyle(fontSize: 24, color: color)),
            const SizedBox(height: 16),
            Text(_advice, textAlign: TextAlign.center),
          ],
        ),
      ),
    );
  }
}

🎨 Fitur-Fitur Unggulan Aplikasi

1. Interface yang Intuitif

  • Pilihan gender dengan visual yang jelas

  • Slider untuk tinggi badan yang smooth

  • Tombol plus/minus untuk berat dan usia

  • Hasil dengan warna sesuai kategori

2. Logika Perhitungan yang Akurat

dart
// Rumus BMI: berat(kg) / (tinggi(m) * tinggi(m))
double heightInMeter = _height / 100;
_bmi = _weight / (heightInMeter * heightInMeter);

3. Kategori BMI dengan Warna

  • Underweight (BMI < 18.5) - Biru

  • Normal (18.5 ≤ BMI < 25) - Hijau

  • Overweight (25 ≤ BMI < 30) - Oranye

  • Obese (BMI ≥ 30) - Merah

4. Saran Kesehatan Personal

Setiap kategori memiliki saran yang berbeda untuk membantu user mencapai berat badan ideal.

🔧 Tips Pengembangan Lanjutan

1. Tambahkan Local Storage

dart
// Simpan riwayat perhitungan
import 'package:shared_preferences/shared_preferences.dart';

2. Implementasi Grafik Progress

dart
// Gunakan package charts_flutter
// untuk menampilkan progress BMI over time

3. Tambahkan Fitur Berbagi

dart
// Share hasil ke media sosial
import 'package:share/share.dart';

4. Internationalization

dart
// Dukung multiple bahasa
import 'package:flutter_localizations/flutter_localizations.dart';

🐛 Troubleshooting Common Issues

Issue 1: State Tidak Update

Solution: Pastikan menggunakan setState(() {}) setiap mengubah variabel state.

Issue 2: Layout Overflow

Solution: Gunakan SingleChildScrollView atau ListView untuk konten yang panjang.

Issue 3: Performance Lag

Solution: Optimasi dengan const widget dan hindari rebuild yang tidak perlu.

📊 Statistik BMI (World Health Organization)

KategoriBMI RangeRisiko Kesehatan
Underweight< 18.5Nutrisi kurang, osteoporosis
Normal18.5 - 24.9Risiko rendah
Overweight25 - 29.9Risiko meningkat
Obese I30 - 34.9Risiko tinggi
Obese II35 - 39.9Risiko sangat tinggi
Obese III≥ 40Risiko ekstrim

🎓 Pelajaran yang Didapat

Technical Skills:

  1. State Management: Mengelola state dengan setState

  2. UI Design: Membuat layout yang responsive

  3. User Input: Menangani berbagai jenis input (slider, button, etc.)

  4. Business Logic: Implementasi rumus medis yang akurat

Soft Skills:

  1. Problem Solving: Debugging dan optimization

  2. User Experience: Membuat aplikasi yang mudah digunakan

  3. Attention to Detail: Validasi input dan error handling

🚀 Langkah Selanjutnya

Untuk Pemula:

  1. Coba ubah warna tema

  2. Tambahkan animasi sederhana

  3. Eksperimen dengan layout berbeda

Untuk Intermediate:

  1. Tambahkan Firebase untuk cloud save

  2. Implementasi dark mode

  3. Buat versi web dengan Flutter

Untuk Advanced:

  1. Integrasi dengan health API (Apple Health/Google Fit)

  2. Machine learning untuk prediksi

  3. Social features untuk challenge bersama

💡 Inspirasi untuk Modifikasi

  1. Themed BMI Calculator: Tema sesuai musim atau hari raya

  2. Gamifikasi: Hadiah untuk mencapai target BMI

  3. Meal Planner: Integrasi dengan rekomendasi makanan

  4. Workout Companion: Saran exercise berdasarkan BMI

📱 Demo dan Source Code

Anda bisa mencoba aplikasi ini langsung di Zapp.run atau download source code lengkapnya dari repository GitHub.

🤝 Komunitas dan Kontribusi

Bergabunglah dengan komunitas Flutter Indonesia untuk:

  • Berbagi hasil kreasi Anda

  • Bertanya jika mengalami kesulitan

  • Berkontribusi pada proyek open source

  • Mengikuti workshop dan meetup

🎯 Kesimpulan

Membuat aplikasi BMI Calculator dengan Flutter adalah project yang sempurna untuk belajar mobile development. Anda tidak hanya belajar coding, tetapi juga menciptakan sesuatu yang bermanfaat bagi kesehatan banyak orang.

Remember: Aplikasi ini hanya alat bantu. Untuk diagnosis kesehatan yang akurat, selalu konsultasikan dengan profesional medis.


Siap membuat aplikasi Flutter pertama Anda? Mulailah dengan project sederhana seperti ini, lalu kembangkan sesuai kreativitas Anda. Jangan lupa share hasil karya Anda di komentar!

Happy Coding! 🚀

LINK: https://zvfi065cvfj0.zapp.page/#/

Comments

Popular posts from this blog

Membuat Carousel Gambar Film Marvel dengan Bottom Navigation

Kelompok Flutter

M.Rizky firmansyah design UI/UX