본문 바로가기
Flutter

[Flutter]TextFormField와 Form을 통한 사용자 입력 값 받기

by dong_seok 2023. 8. 12.

TextFormField는 텍스트를 입력하고 입력한 텍스트를 저장유효성 검사를 하기 위한 위젯으로  Form 과 함께 많이 사용합니다. 먼저 TextFormField를 사용하기 위한 방법에 대해서 알아보도록 하겠습니다.

 

1. Globalkey로 Form 만들기

Form 위젯은 여러 양식 필드를 그룹화하고 유효성을 검사하기 위한 컨테이너 역할을 합니다. 양식을 만들때 GlobalKey를 이용하여 Form을 고유하게 식별하고 이후에 여러 양식 필드의 유효성을 검사할 수 있습니다. GlobalKey는 요소를 식별하고 다른 키로의 액세스를 제공한다고 합니다. 그리고 상위 위젯에 적용했을 시 하위 위젯에까지 적용이 된다고 합니다. 저는 Form에 글로벌키를 사용하고,  하위 위젯인 TextFormField의 유효성을 체크하는 코드를 작성할 계획입니다.

 

final formkey = GlobalKey<FormState>();
String content = '';

 

먼저 GlobalKey<FormState>( )를 이용하여 formkey를 선언해 준 후 사용자 입력값을 저장할 content라는 이름의 state를 하나 만들어줍니다. 그리고나서 아래처럼 Form 위젯을 만들어줍니다.

 

Form(
          key: formkey,
          child: Column(
          )

주의해야 할 점은 GlobalKey <MyCustomFormState>가 아니고, 항상 GlobalKey <FormState>입니다. 

 

2. TextFormField에 유효성 검사 로직 추가

Form이 있지만 사용자가 텍스트를 입력할 수 있는 방법이 없습니다. 이때 사용자로부터 입력을 받기위해  TextFormField 위젯을 사용합니다. 이때 validator() 함수를 이용하여 입력의 유효성을 검사합니다.

TextFormField(                        
                        onSaved: (value) {
                          // 내용 작성하면 content에 저장
                          setState(() {
                            content = value as String;
                          });
                        },
                        
                        validator: (value) {
                          if (value == null || value.isEmpty) {
                            return '내용을 입력해주세요';
                          }
                          return null;
                        },
                      ),

 

validator:(value)에서 value 값은 사용자 입력 값을 말하고 값을 받아와서 조건을 검사합니다. if문의 조건에 해당 할 경우 TextFormField 하단에 에러메시지를 출력하고 조건에 해당하지 않을경우 null을 리턴합니다. 이번 예에서는 필드가 비어있으면 에러를 출력하고 내용이 적혀있으면 null을 리턴하도록 했습니다. 그 위의 onSaved는 사용자 입력값을 받아서 content state에 저장하는 함수입니다.

 

3. 양식을 확인하고 제출하는 버튼을 만듭니다.

Form과 TextFormField를 모두 만들었으니 사용자가 양식을 작성하였을때 제출 할 수있도록 버튼을 만들 차례입니다.

버튼을 만드는 방법은 여러가지겠지만 저는 ElevatedButton 위젯을 사용하였습니다. 먼저 버튼을 눌렀을때 이벤트가 처리 되도록 onPressed() 함수를 구현하였습니다.

ElevatedButton(
                        onPressed: () {
                          if (formkey.currentState!.validate()) {                            
                            formkey.currentState!.save(); // onSaved()
                            ScaffoldMessenger.of(context).showSnackBar(
                              SnackBar(content: Text(content)),
                            );
                          }
                        },                        
                        child: const Text('작성 완료'),
                      ),

 

양식의 유효성을 검사하기 위해서 1번에서 만들었던 formkey를 사용합니다.그리고 GlobalKey의 하위 메소드 currentState를 사용해줍니다. validate()메소드가 호출되면 양식의 각 TextFormField에 대해 validate() 함수를 실행합니다. 모든 validate() 함수에 문제가 없다면 메서드는 null을 반환하고 필드에 오류가 있으면 양식에 해당하는 오류 메시지를 표시할 것입니다. 그후에  2번에서 만들었던 onSaved() 함수를 사용해서 content에 사용자로부터 입력받은 값을 저장합니다. 위의 코드들을 실행해보면 다음과 같은 결과를 얻을 수 있습니다.

이게 입력 값을 받지 않은 모습이고 이 상태에서 버튼을 누르게 되면

validator()함수에서 작성했던 에러메시지가 출력되는 모습을 볼 수 있습니다. 다시 내용을 작성하고 버튼을 누르게 되면

정상적으로 버튼이 눌리는 모습을 볼 수 있습니다. 추가적으로 우리가 작성한 내용이 content에 정상적으로 저장 되어있는 모습도 같이 볼 수 있습니다.

 

하지만 이렇게만 보면 폼이 별로 안이쁘고 사용하기에 조금 불편한 부분이 있습니다. 다음 포스팅에는 TextFormField에 있는 여러가지 기능들을 사용해서 조금 더 꾸며보도록 하겠습니다.

 

 

참고자료

https://kibua20.tistory.com/236

https://docs.flutter.dev/cookbook/forms/validation

댓글