Flutter Forms
≡ 목차 (Table of Contents)
이 글은 Flutter에서 폼(Form)을 만드는 가장 기초적인 코드를 예제 위주로 설명한다.
Flutter Forms 예제
다짜고짜 그냥 예제만 보자. 필수적이면서도 기본적인 기능만 포함한 단순한 Dart 코드 예제다.
class MyFormWidget extends StatelessWidget { final _formKey = GlobalKey<FormState>(); // 값을 액세스 해야 한다면 TextEditingController가 필요. // 여기서 someValue는 가상의 옵셔널 인스턴스. // 이 인스턴스가 동적이지 않다면 late는 빼도 된다. // 기본값이 필요 없다면 아예 내부의 필드를 다 빼도 된다. late final _textEditingController = TextEditingController(text: someValue ?? "default value"); @override Widget build(BuildContext context) { ... Form( key: _formKey, child: Column( children: [ // 일반적인 텍스트 필드 TextFormField( // 기본값. someInitialValue는 가상의 값 initialValue: someInitialValue, decoration: const InputDecoration(labelText: "Some Text Field 1"), onChanged: (value) { // 값이 바뀔 때마다 호출된다. print("value = $value"); }), // 컨트롤러를 사용하는 텍스트 필드 // 덤으로 우측에 삭제 버튼 // 컨트롤러를 사용할 때는 initialValue 필드는 무의미해진다. TextFormField( controller: _textEditingController, decoration: const InputDecoration( labelText: "Some Text Field 2", suffixIcon: IconButton( onPressed: _textEditingController.clear, icon: Icon(Icons.clear)))), // 값 유효성 확인 TextFormField( initialValue: "Validation Available", decoration: const InputDecoration(labelText: "Some Text Field 3"), validator: (value) { if (isValid(value)) { // 유효하지 않을 때 표시할 메세지 return "The value is invalid"; } else { return null; } }), ] ) ), ... // 폼을 전송하는 용도의 버튼 TextButton( child: const Text("Submit"), onPressed: () { // 컨트롤러를 통해 텍스트 필드의 값을 얻을 수 있음 print("${_textEditingController.text}") // 유효성 체크 if (_formKey.currentState!.validate()) { // 문제가 없는 경우 // send()는 가상의 메서드 send(); } else { // 문제가 있을 때 취할 행동 // showError()는 가상의 메서드 showError("Failed to validates"); } } ) } }
위 코드는 스테이트리스 위젯 클래스에서 폼에 필요한 부분만 남기고 ...
으로 표시된 부분은 많은 코드가 생략된 부분이니 그 점에 유의하자.
각 필드의 값 읽기
각 필드의 값을 읽는 방법은 몇 가지가 있는데 여기서는 두 가지만 알아보자.
onChanged
필드에 포커스를 준 뒤 뭔가를 입력하면 onChanged 필드의 클로저가 매번 호출된다. 여기서 값을 알 수 있다.
별도의 제출 버튼 없이 폼 필드만 수정하면 자동으로 업데이트 되게 하고 싶다면 이 필드를 이용하면 될 것 같다.
TextEditingController
만약 폼 필드 내부가 아닌 다른 로직에서 필드에 입력된 값을 액세스 해야 한다면 TextEditingController 인스턴스를 컨트롤러로 넘겨줘야 한다.
위 코드에서 _textEditingController
라고 이름이 붙은 프로퍼티가 그 부분이다.
값을 읽을 때는 이 컨트롤러의 값, 여기서는 .text
멤버 프로퍼티를 액세스 해서 텍스트 필드의 값을 읽을 수 있었다.
기타
FormKey
폼은 그룹으로 분류할 수 있으며 한 화면에 여러 그룹의 폼이 있을 수 있다. 이때 각 폼 그룹은 키를 이용해 구분한다.
심지어 각 키는 해당 그룹의 폼을 대상으로 몇 가지 기능을 수행하기도 한다. 예를 들어 각 필드의 validator 필드의 클로저는 FormKey의 validate() 메서드가 호출되지 않으면 실제로 실행되지 않는다.
따라서 Flutter의 폼(Forms)은 사실상 필수적으로 키가 필요하게 구현되어 있는 것 같다.
InputDecoration
InputDecoration을 이용해 필드에 여러 꾸미기나 부가기능을 제공할 수 있다. 예를 들자면 labelText
를 이용해 필드 이름을 표시해 주거나, prefixIcon
이나 suffixIcon
등으로 필드 앞과 뒤에 아이콘을 넣을 수도 있다. 위 예제처럼 아예 suffixIcon
에 버튼을 넣어 삭제 기능을 구현하는 등 다양한 활용이 가능하다.