[TIL] flutter - BMI Calculator

김영광·2025년 12월 17일

오늘은 머리가 너무 아파서 간단하게 적고 퇴근해야겠다..

🔎 BMI Calculator

1️⃣ main

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

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

  
  Widget build(BuildContext context) {
    return MaterialApp(
      themeMode: ThemeMode.dark,
      theme: ThemeData(
        useMaterial3: true,
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.deepPurple,
          brightness: Brightness.light,
        ),
        dividerColor: Colors.black
      ),
      darkTheme: ThemeData(
        useMaterial3: true,
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.pinkAccent,
          brightness: Brightness.dark,
        ),
        dividerColor: Colors.white
      ),
      home: HomePage(),
    );
  }
}

2️⃣ HomePage

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

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: MainAppBar(title: "BMI CALCULATOR"),
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            GenderBox(),
            SliderBox(type: "Height", unit: "cm"),
            SliderBox(type: "Weight", unit: "kg"),
            ElevatedButton(onPressed: () {}, child: Container()),
          ],
        ),
      ),
    );
  }
}

3️⃣ GenderBox

import 'package:flutter/material.dart';

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

  
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          GenderBoxItem(icon: Icons.male, gender: "MALE"),
          SizedBox(width: 10),
          GenderBoxItem(icon: Icons.female, gender: "FEMALE"),
        ],
      ),
    );
  }
}

class GenderBoxItem extends StatelessWidget {
  const GenderBoxItem({super.key, required this.icon, required this.gender});

  final IconData icon;
  final String gender;

  
  Widget build(BuildContext context) {
    return Expanded(
      child: Container(
        padding: EdgeInsets.all(15),
        width: 200,
        height: 150,
        decoration: BoxDecoration(
          border: Border.all(color: Theme.of(context).dividerColor),
        ),
        child: Stack(
          children: [
            Container(
              alignment: Alignment.topLeft,
              width: double.infinity,
              height: double.infinity,
              child: Icon(icon, color: Colors.grey[350], size: 70),
            ),
            Container(
              alignment: Alignment.bottomRight,
              width: double.infinity,
              height: double.infinity,
              child: Text(
                gender,
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                  fontSize: 24,
                  color: Colors.grey[350],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

5️⃣ slider

class SliderBox extends StatefulWidget {
  const SliderBox({super.key, required this.type, required this.unit});

  final String type;
  final String unit;

  
  State<SliderBox> createState() => _SliderBoxState();
}

class _SliderBoxState extends State<SliderBox> {
  double value = 100;

  void onChangeValue(double newValue) {
    setState(() {
      value = newValue;
    });
  }

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          crossAxisAlignment: CrossAxisAlignment.end,
          children: [
            Text(widget.type),
            Text("${value.toStringAsFixed(0)} ${widget.unit}"),
          ],
        ),
        SliderWidget(value: value, onChangeValue: onChangeValue),
      ],
    );
  }
}

class SliderWidget extends StatelessWidget {
  const SliderWidget({
    super.key,
    required this.value,
    required this.onChangeValue,
  });

  final double value;
  final void Function(double) onChangeValue;
  
  Widget build(BuildContext context) {
    return Slider(value: value, onChanged: onChangeValue, min: 1, max: 250);
  }
}

4️⃣ appBar

class MainAppBar extends StatelessWidget implements PreferredSizeWidget {
  const MainAppBar({super.key, required this.title, this.actions});

  final String title;
  final List<Widget>? actions;

  
  Widget build(BuildContext context) {
    return AppBar(
      title: Text(title, style: TextStyle(color: Colors.amber)),
      actions: actions,
      centerTitle: true,
    );
  }

  
  Size get preferredSize => Size(double.infinity, 52);
}
profile
주니어 개발자

0개의 댓글