[FLUS 스터디 7주차] Flutter 기초 - Components Widgets

sucream·2022년 10월 16일
0

flutter-study

목록 보기
15/17
post-custom-banner

오늘은 주로 사용자 인터랙션과 관련된 컴포넌트들에 대해 알아보고자 한다.

Switch

무언가를 껐다 켤 때 사용하는 위젯으로, 우리에게 충분히 익숙한 위젯이다. 참고로 onChanged 부분이 null로 설정되있다면, 해당 스위치는 사용할 수 없는 disabled 상태가 된다.

class SwitchTest extends StatefulWidget {
  const SwitchTest({Key? key}) : super(key: key);

  
  State<SwitchTest> createState() => _SwitchTestState();
}

class _SwitchTestState extends State<SwitchTest> {
  bool _switchValue = false;  // 스위치의 상태를 위한 플래그 변수

  // 스위치를 누를 때 실행될 함수
  void _onChanged(bool value) {
    setState(() {
      _switchValue = value;
    });
  }

  
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Visibility(  // Visibility 위젯을 이용하면 위젯을 보이거나 숨길 수 있음
          visible: _switchValue,
          maintainState: true,
          maintainAnimation: true,
          maintainSize: true,
          child: Image.asset('images/icon1.png'),  // 여기서는 이미지를 보이거나 숨김
        ),
        Switch( 실제 스위치 위젯
          value: _switchValue, 현재 스위치의 상태값
          onChanged: (bool value) => _onChanged(value),  // 스위치를 누르면 해당 값이 함수에 전달됨
        ),
        Text(
          'Switch value: $_switchValue',
          style: const TextStyle(fontSize: 20),
        ),
        const Text(
          '스위치를 누르면 포챠펭이 나타납니다.',
          style: TextStyle(fontSize: 20),
        ),
      ],
    );
  }
}

Checkbox

체크박스의 경우도 우리에게 익숙한 형태의 위젯이다. 스위와 마찬가지로 onChanged가 null이면 체크박스를 클릭할 수 없다. 아래 예제는 다수의 체크박스가 있을 때 해당 체크박스를 클릭하면 옆에 있는 이미지가 표현된다.

class CheckboxTest extends StatefulWidget {
  const CheckboxTest({Key? key}) : super(key: key);

  
  State<CheckboxTest> createState() => _CheckboxTestState();
}

class _CheckboxTestState extends State<CheckboxTest> {
  // 각 체크박스들의 상태를 저장하기 위한 변수
  List<bool> checkboxValueList = [false, false, false];
  // 각 이미지 파일들의 위치를 저장하는 변수
  List<String> imageNameList = ['icon1.png', 'icon2.png', 'icon3.png'];

  
  Widget build(BuildContext context) {
    return ListView.separated(  // 다수의 내용을 반복적으로 화면에 출력하기 위해 ListView를 사용했음
      itemCount: checkboxValueList.length,
      separatorBuilder: (context, index) => const Divider(
        height: 5,
        color: Colors.deepPurpleAccent,
      ),
      itemBuilder: (BuildContext context, int index) {  // 아이템 빌더로 화면에 반복적으로 표현될 데이터를 구성
        return Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('포챠${index + 1}', style: const TextStyle(fontSize: 20)),
            Checkbox(  // 체크박스 위젯
              value: checkboxValueList[index],
              onChanged: (bool? value) {  // 익명함수를 사용하여 바로 내역이 반영되도록 함
                setState(() {
                  checkboxValueList[index] = value!;
                });
              },
            ),
            Visibility(  // Visibility 위젯을 사용
              visible: checkboxValueList[index],
              maintainState: true,
              maintainAnimation: true,
              maintainSize: true,
              child: Image.asset(
                'images/${imageNameList[index]}',
                width: 200,
              ),
            ),
          ],
        );
      },
    );
  }
}

Radio

체크박스가 중복 가능하게 선택이 가능하다면, 라디오 버튼은 같은 카테고리 내에서 하나의 항목을 선택하기 위해 사용한다. 라디오 버튼은 일종의 그룹을 이루어야 하며 각 버튼은 groupValue라고 하는 값으로 그룹을 지정할 수 있다.

class RadioTest extends StatefulWidget {
  const RadioTest({Key? key}) : super(key: key);

  
  State<RadioTest> createState() => _RadioTestState();
}

class _RadioTestState extends State<RadioTest> {
  int _radioValue = 0; // 같은 그룹의 라디오 버튼이 공유하는 변수
  List<String> imageNameList = ['icon1.png', 'icon2.png', 'icon3.png'];

  void _handleRadioValueChange(int? value) {
    setState(() {
      _radioValue = value!;
    });
  }

  
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: 3,
      itemBuilder: (BuildContext context, int index) {
        return Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('포챠${index + 1}', style: const TextStyle(fontSize: 20)),
            Radio(
              value: index,
              groupValue: _radioValue, // 이 값이 있어야 서로 같은 그룹의 라디오로 사용 가능
              onChanged: (int? value) => _handleRadioValueChange(value),
            ),
            Visibility(
              visible: _radioValue == index, // 인덱스 비교를 통해 선택된 라디오 버튼만 이미지를 보여줌
              maintainState: true,
              maintainAnimation: true,
              maintainSize: true,
              child: Image.asset(
                'images/${imageNameList[index]}',
                width: 200,
              ),
            ),
          ],
        );
      },
    );
  }
}

Slider

범위 내에 있는 값을 선택할 때 유용하게 사용할 수 있는 슬라이더 위젯으로, 기본적으로 연속적인 값을 선택할 수 있으며, divisions에 특정 정수를 지정하면 범위를 해당 갯수만큼 불연속적 선택이 가능하다.

class SliderTest extends StatefulWidget {
  const SliderTest({Key? key}) : super(key: key);

  
  State<SliderTest> createState() => _SliderTestState();
}

class _SliderTestState extends State<SliderTest> {
  double _sliderValue = 0.0;

  void _onChanged(double value) {
    setState(() {
      _sliderValue = value;
    });
  }

  
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        SizedBox(
          height: 300,
          child: Image.asset(
            'images/icon1.png',
            width: _sliderValue,
          ),
        ),
        Slider(
          value: _sliderValue,
          min: 0.0,
          max: 200.0,
          // divisions: 10,  // 10개의 구간으로 나누어서 표시, 없으면 연속적
          label: '$_sliderValue',
          onChanged: (double value) => _onChanged(value),
        ),
        Text(
          'Slider value: ${_sliderValue.toInt()}',
          style: const TextStyle(fontSize: 20),
        ),
      ],
    );
  }
}

showDatePicker

TextField

ExpansionPanel

SnackBar

BottomSheet

SimpleDialog

AlertDialog

Refference

profile
작은 오븐의 작은 빵
post-custom-banner

1개의 댓글

comment-user-thumbnail
2022년 10월 19일

포챠펭이 너무 귀엽습니다ㅋㅋㅋㅋ 좋은 글 감사해요!!

답글 달기