본문 바로가기

카테고리 없음

[Flutter_개발] BMI 계산기 앱 만들기

이번 강의에서는 Flutter를 활용해 BMI(Body Mass Index) 계산기 앱을 구현했다.
단순히 BMI를 계산하는 기능뿐 아니라, 앱 구조 설계, 테마 적용, 페이지 전환, 위젯 분리 등 실제 앱 개발에 필요한 핵심 개념들을 학습했다.

프로젝트 구조 설계

앱은 크게 입력 화면(HomePage) 과 결과 화면(ResultPage) 으로 구성된다.

  • HomePage: 사용자가 성별, 키, 몸무게를 입력하는 페이지
  • ResultPage: 계산된 BMI 값을 시각적으로 출력하는 페이지
 

이렇게 페이지별 폴더를 나누면, 화면이 여러 개인 프로젝트에서도 파일 관리와 유지보수가 쉬워진다.

main.dart 기본 세팅

main.dart에서는 앱 전체 구조를 관리한다.

  • MaterialApp의 home 속성에 HomePage()를 지정하여 앱 시작 시 보여줄 첫 화면을 설정.
  • theme, darkTheme 속성을 통해 라이트/다크 모드를 모두 지원하도록 구성했다.
return MaterialApp(
  theme: ThemeData(
    useMaterial3: true,
    colorScheme: ColorScheme.fromSeed(
      seedColor: Colors.pinkAccent,
      brightness: Brightness.light,
    ),
  ),
  darkTheme: ThemeData(
    useMaterial3: true,
    colorScheme: ColorScheme.fromSeed(
      seedColor: Colors.pinkAccent,
      brightness: Brightness.dark,
    ),
  ),
  home: HomePage(),
);
 

이때 ColorScheme.fromSeed를 사용하면 앱의 메인 컬러를 기준으로 전체 색상이 자동 생성되어 일관된 디자인을 유지할 수 있다.
또한 themeMode: ThemeMode.system으로 설정하면 기기의 다크모드 설정을 따라가게 된다.

ThemeData의 개념과 활용

이전까지는 위젯마다 개별적으로 색상과 스타일을 지정했다면,
ThemeData를 사용하면 앱 전체 위젯에 공통 테마를 적용할 수 있다.

예를 들어 모든 AppBar의 배경색, 모든 TextButton의 스타일을 일괄 지정 가능하다.
이 방식을 통해 중복 코드를 줄이고 디자인 변경 시 유지보수성을 높였다.

 
theme: ThemeData(
  appBarTheme: AppBarTheme(
    backgroundColor: Colors.pinkAccent,
  ),
  textTheme: TextTheme(
    bodyMedium: GoogleFonts.merriweather(),
  ),
)

HomePage 구현

HomePage는 사용자 입력 UI를 담당하며, Column 위젯을 사용해 세로로 배치했다.
내부는 크게 다음 세 부분으로 구성된다.

  1. 성별 선택 영역 (GenderBox)
    • Container, Icon, Text 위젯을 조합해 남/여 선택 박스를 구성.
    • 클릭 시 선택 상태를 변경하도록 추후 StatefulWidget으로 확장 가능.
  2. 키 입력 영역 (HeightBox)
    • Slider 위젯을 사용해 사용자가 키를 직관적으로 조절 가능.
    • 현재 입력값은 Text로 실시간 표시.
  3. 몸무게 입력 영역 (WeightBox)
    • 구조가 HeightBox와 거의 동일하여 재사용 가능한 컴포넌트로 분리.
Slider(
  value: height,
  min: 100,
  max: 220,
  onChanged: (value) {
    setState(() {
      height = value;
    });
  },
);
 

이런 식으로 각각의 UI 요소를 작은 위젯으로 나누어 관리하면, 유지보수와 재사용이 용이하다.


페이지 전환 (Home → Result)

BMI 계산 버튼을 누르면 결과 페이지로 이동하도록 구현했다.
Navigator.push를 이용해 페이지를 전환하며, 계산된 값을 함께 전달한다.

 
ElevatedButton(
  onPressed: () {
    double bmi = weight / ((height / 100) * (height / 100));
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => ResultPage(bmi: bmi),
      ),
    );
  },
  child: Text('결과 보기'),
);

 

ResultPage 구현

ResultPage는 BMI 값을 시각적으로 표현하는 화면이다.
구성 요소는 다음과 같다.

  • ResultGauge 위젯: BMI 범위(저체중, 정상, 과체중 등)에 따라 색상 변화 표시
  • ResultText 위젯: 계산된 BMI 값과 결과 텍스트 출력
  • OutlinedButton: 다시 입력 화면으로 돌아가는 버튼 (Navigator.pop)

 

BMI 값을 구하는 공식을 사용해 값에따라 다음과 같이 결과를 나눴다.

  • 18.5 미만 → 저체중
  • 18.5 ~ 24.9 → 정상
  • 25 이상 → 과체중
 
Text(
  bmi.toStringAsFixed(1),
  style: TextStyle(fontSize: 50, fontWeight: FontWeight.bold),
);

 

이번 BMI 계산기 프로젝트를 통해 Flutter의 기본 구조를 깊이 이해할 수 있었다.
특히 테마 관리(ThemeData)와 페이지 간 이동(Navigator) 부분은 이후 다른 앱을 만들 때도 핵심이 될 기능이라 느꼈다.
또한, 단순히 화면을 만드는 것에서 그치지 않고 구조적 설계와 재사용 가능한 컴포넌트 개발 방식을 익힐 수 있었다.