이번 강의에서는 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 위젯을 사용해 세로로 배치했다.
내부는 크게 다음 세 부분으로 구성된다.
- 성별 선택 영역 (GenderBox)
- Container, Icon, Text 위젯을 조합해 남/여 선택 박스를 구성.
- 클릭 시 선택 상태를 변경하도록 추후 StatefulWidget으로 확장 가능.
- 키 입력 영역 (HeightBox)
- Slider 위젯을 사용해 사용자가 키를 직관적으로 조절 가능.
- 현재 입력값은 Text로 실시간 표시.
- 몸무게 입력 영역 (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) 부분은 이후 다른 앱을 만들 때도 핵심이 될 기능이라 느꼈다.
또한, 단순히 화면을 만드는 것에서 그치지 않고 구조적 설계와 재사용 가능한 컴포넌트 개발 방식을 익힐 수 있었다.