Flutter VOD 강의_예제 4번-2 BMI계산기

주혜림·2025년 12월 21일

Flutter VOD 강의_예제 4번-1 링크
BMI계산기 만들기를 강의를 보면서 이어서 코드 짜보기. VOD 1-13까지
클래스를 구성하고 몰랐던 위젯들과 기능에 대해서 알아보자
나름대로 UI에 대해 분석도 하고 구상도 해봤는데 내 생각과 어떤점이 달랐는지, 새로 배운건 무엇인지 즐겁게 진행해 봐야겠다!

⭐️ 다양한 Class 기능들

▶︎ Flutter.dev 홈페이지

Meterial-Scaffold class 문서를 참조하면 지원하는 Class들에 대한 정보를 볼 수 있다.
다양한 기능들을 전부 외울 수 있다면 좋겠지만,
문서들을 찾아보며 어떤 기능이 있는지 찾아보고, 적용시킬지 해결 방법을 찾는 것이 가장 빠른 방법이다!
(각종 예제들 까지!)


🔽 theme.dart 파일 에서

⁉️ [ 이건 무슨 속성? ]

ButtonStyle 내 속성은 WidgetStateProperty 클래스를 사용해야 한다.

  • 버튼의 상태, 누르거나 마우스를 올렸을 때 상태별 스타일 정의 클래스

ResultGauge 동그란 게이지를 표현하는 위젯
CircleProgressIndicator 라는 위젯을 사용해서 구현

  • theme에서 ProfressIndicatorTheme 속성으로 스타일을 정의할 수 있지만 구현할 때 두 색상의 CircleProgressIndicator 위젯을 사용해야 해서 쓰지 않는다.

파라미터를 함수에 적용해서 출력하는 방법

🔽 Slider 위젯을 완성해서 출력한 모습

home_page.dart 파일
slider_box.dart 파일을 home_page에서 출력할 때

class HomePage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('BMI CALCULATOR')),

      body: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 20),
        child: Column(
          children: [
            // 슬라이더 박스에서 넘어와서..
            // 전구표시를 누르면 넘길 변수의 이름을 지정해서 넘길 수 있다!!!
            GenderBox(),
            SliderBox(label: 'HEIGHT', value: 170, unit: 'cm'),
            SliderBox(label: 'WEIGHT', value: 70, unit: 'kg'),
          ],

출력이 안된다면,
slider Class의 파라미터를 빌드 함수에 적용시켜야 함

class SliderBox extends StatelessWidget {
  // 위젯에서 아래 3가지 변수를 전달받기 위해서 생성자를 만들어줌!
  SliderBox({
    // 네임드 파라미터로 사용.
    // home_page로 가서 넘길 변수를 적용 시키기
    required this.label,
    required this.value,
    required this.unit,
  });

  String label;
  // '170' int가 아니라 슬라이더와 같이 써줘야 하기 때문에 double
  double value;
  String unit;

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        Row(
          crossAxisAlignment: CrossAxisAlignment.end,
          children: [
            Text(
              // 파라미터를 가져오지 않으면 출력이 되지 않음
              'HEIGHT',
            ),
            // 텍스트 사이 간격 만들어줌
            Spacer(),
            Text(
            // 파라미터 가져오기
              '170',
            ),
            Text(
            // 파라미터 가져오기
              'cm',
            ),
          ],
        ),
        Slider(
          value: 170,
          onChanged: (v) {},
          min: 1,
          max: 300,
        ),
      ],
    );
  }
}

수정해준다.

class SliderBox extends StatelessWidget {
  
  SliderBox({
    required this.label,
    required this.value,
    required this.unit,
  });

  String label;
  double value;
  String unit;

  
  Widget build(BuildContext context) {
    // return Text('Slider Box');
    return Column(
      children: [
        Row(
          crossAxisAlignment: CrossAxisAlignment.end,
          children: [
            Text(
              //  'HEIGHT', -> 파라미터를 가져와야 적용이 된다!
              label,
              style: TextStyle(fontSize: 20),
            ),
            Spacer(),
            Text(
              // '170', -> 파라미터를 가져와야 적용이 된다!
              value.toStringAsFixed(0),
              style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
            ),
            Text(
              // 'cm', -> 파라미터를 가져와야 적용이 된다!
              unit,
              style: TextStyle(fontSize: 20),
            ),
          ],
        ),
        Slider(
          // value: 170, -> 슬라이더도 파라미터 가져와야 적용된다.
          value: value,
          onChanged: (v) {},
          min: 1,
          max: 300,
        ),
      ],
    );
  }
}

⁉️ [ 이건 무슨 함수? ]

.toStringAsFixed(0)

소수점이 들어간 double타입의 고정된 소수점 값을 String 으로 바꿔주는 함수. 1을 적용시키면 0.0 소수점이 적용된다.

  • (0)일 경우 출력은 -> 170cm
  • (1)일 경우 출력은 -> 170.0cm

(예시)

value.toStringAsFixed(0),

🌈 StatefulWidget을 이해하자

기본 UI구성이 끝나면, 버튼과 슬라이더를 StatefulWidjet으로 바꿔줘서 값을 사용자가 변경할 수 있게 만들어준다!

  • StatelessWidjet: 고정된 값을 가지는 위젯
  • StatefulWidjet: 변경 가능한 값을 가지는 위젯

HopmePage클래스를 StatefulWidjet으로 바꿔준다.

class HomePage extends StatefulWidget {
  
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  // StatefulWidget
  // 젠더박스
  bool isMale = true;
  double height = 170;
  double weight = 70;

class _HomePageState의 젠더박스에 적용될 함수 값이 변경되었을 때(StatefulWidget) 실행시킬 함수를 각각 정리해줘야함

- StatefulWidget에서는 상태가 바뀌면 stetState를 꼭 호출해줘야 한다!!


젠더박스와 슬라이더를 움직였을 때 실행되는 함수도 만들어준다.

class HomePage extends StatefulWidget {
  
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

  // 젠더박스
  bool isMale = true;
  Void onGenderChanged(bool male) {
    setState(() {
      // 남자를 클릭하면 남자성별이 선택된다.
      isMale = male;
    });
  }
  
  // 키와 몸무게 슬라이더 박스도 적용시켜준다!
  double height = 170;
  Void onHeightChanged(double newHeight) {
    setState(() {
      height = newHeight;
    });
  }

  double weight = 70;
  void onWeightChanged(double newWeight) {
    setState(() {
      weight = newWeight;
    });
  }

변수와 함수 선언 끝!


각 위젯으로 넘겨줘서 변수값을 초기화 시켜준다.

-상위인 HomePage의 함수를 전달받아서 실행하려면 Function타입의 변수를 선언. (변수명: onChanged)

class GenderBox extends StatelessWidget {
  // StatefulWidget. 아래 변수를 초기화해주고 전달받을 수 있도록 함
  GenderBox(this.isMale, this.onChanged);

  // StatefullWidget 함수와 변수를 각 위젯에서 넘겨준다.
  bool isMale;
  void Function(bool newValue) onChanged;

'MALE', true -> 위의 불리안 변수를 가져와서 변경해줌. isMale
'FEMALE', false -> true가 아닐 때 활성화 되는 것이기 때문에. !isMale


  Widget build(BuildContext context) {
    return Row(
      children: [
        gender(context, Icons.male, 'MALE', isMale),
        SizedBox(width: 8),
        gender(context, Icons.female, 'FEMALE', !isMale),
      ],
    );

적용시키는 Class가 변경되었을 때, 변수를 적용시키는 부분을 잊지말고 꼭 변경해줘야 반영이 된다!
이 부분이 아직 너무 헷갈리지만 어떤 원리인지는 조금씩 이해하고 있다..


[ 발생한 오류들 ]

젠더박스까지 StatefulWidget 적용을 시키고 실행을 해보려고 했더니
무언가 return시키는 값이 빠져버렸다!!
오류로 인해 시뮬레이터가 작동하지 않는데 강의를 보고 따라했음에도 발생한 문제여서 return되는 값이 어디가 잘못되었는지 원인을 찾아보아야겠다.

[ 해결 ]

profile
앱 개발을 공부중입니다.

0개의 댓글