플러터 DropDownButton vs. DropdownButtonFormField

HyunHo Shin·2023년 6월 3일
0

플러터에서 드랍다운 메뉴를 제공하는 위젯은 DropdownButton, DropdownButtonFormField 두가지 입니다.

두 위젯은 UI 상으로는 거의 동일한 모습을 보입니다.

그렇다면 어떤 상황에 각각의 위젯을 사용할까요?

  • DropDownButton: 드랍다운메뉴가 필요한 일반적 상황에 사용
  • DropdownButtonFormField: 유저가 입력을 했는지 확인이 필요한 상황에 사용

이해를 위해 예시를 살펴보도록 하겠습니다.


1. DropDownButton 예시

DropdownButton<String>(
  value: dropdownValue,
  onChanged: (String? newValue) {
    setState(() {
      dropdownValue = newValue!;
    });
  },
  items: <String>['One', 'Two', 'Three', 'Four']
      .map<DropdownMenuItem<String>>((String value) {
    return DropdownMenuItem<String>(
      value: value,
      child: Text(value),
    );
  }).toList(),
)

해당 위젯은 4가지의 선택지 중 하나를 선택하는 옵션을 유저에게 제공합니다.
하지만 유저가 선택을 했는지 안했는지는 판단할 수 없습니다.


2. DropdownButtonFormField 예시

DropdownButtonFormField<String>(
  value: dropdownValue,
  onChanged: (String? newValue) {
    setState(() {
      dropdownValue = newValue!;
    });
  },
  items: <String>['One', 'Two', 'Three', 'Four']
      .map<DropdownMenuItem<String>>((String value) {
    return DropdownMenuItem<String>(
      value: value,
      child: Text(value),
    );
  }).toList(),
  validator: (value) {
    if (value == null || value.isEmpty) {
      return 'Please select an option';
    }
    return null;
  },
)

이와 반대로 DropdownButtonFormField는 validator 프로퍼티를 가지고 있습니다.
해당 프로퍼티를 통해, 만약 유저가 드랍다운 메뉴에 입력을 하지 않았을 경우, 경고문을 출력할 수 있습니다.

위의 예시의 경우 사용자가 아무 것도 선택하지 않았을 경우 ‘Please select an option’이 출력됩니다.

다음 단락에서는 해당 내용을 반영한 더 자세한 예시를 살펴보겠습니다.


3. DropdownButtonFormField: 실전 예제

import 'package:flutter/material.dart';

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

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

  
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: MyCustomForm(),
      ),
    );
  }
}

class MyCustomForm extends StatefulWidget {
  const MyCustomForm({super.key});

  
  MyCustomFormState createState() {
    return MyCustomFormState();
  }
}

class MyCustomFormState extends State<MyCustomForm> {
  final _formKey = GlobalKey<FormState>();
  String? dropdownValue;

  
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 16),
            child: DropdownButtonFormField<String>(
              value: dropdownValue,
              icon: const Icon(Icons.arrow_downward),
              decoration: InputDecoration(
                labelText: 'Select an Option',
                enabledBorder: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(10.0),
                ),
              ),
              items: <String>['Option 1', 'Option 2', 'Option 3', 'Option 4']
                  .map<DropdownMenuItem<String>>((String value) {
                return DropdownMenuItem<String>(
                  value: value,
                  child: Text(value),
                );
              }).toList(),
              onChanged: (String? newValue) {
                setState(() {
                  dropdownValue = newValue!;
                });
              },
              validator: (value) {
                if (value == null || value.isEmpty) {
                  return 'Please select an option';
                }
                return null;
              },
            ),
          ),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 16),
            child: ElevatedButton(
              onPressed: () {
                if (_formKey.currentState!.validate()) {
                  ScaffoldMessenger.of(context).showSnackBar(
                      const SnackBar(content: Text('Processing Data')));
                }
              },
              child: const Text('Submit'),
            ),
          ),
        ],
      ),
    );
  }
}
profile
관심사가 다양한 사람

0개의 댓글