flutter / Form에서 TextField 여러 개 쓰기

rO_Or·2024년 4월 10일

Dart 그리고 Flutter

목록 보기
11/19

Form에서는 여러 개의 텍스트 필드를 사용하게 되는데,
하나씩 관리하는 것보다, 한꺼번에 관리하는 게 낫지 않을까 해서, 찾아본 결과.

텍스트 필드 생성 클래스

import 'package:flutter/material.dart';

class RenderTextField extends StatelessWidget {
  const RenderTextField({
    super.key,
    required this.label,
    required this.onSaved,
    required this.validator,
  });

  final String label; // 라벨 표시 ex) 아이디
  final FormFieldSetter onSaved; // 전송이나 저장 버튼 눌렀을 시 변수에 저장하는 함수
  final FormFieldValidator validator; // 값을 검증하는 함수

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        Row(
          children: [
            Text(
              label,
              style: TextStyle(
                fontSize: Theme.of(context).textTheme.displayLarge?.fontSize,
                color: Theme.of(context).colorScheme.primary,
              ),
            ),
          ],
        ),
        TextFormField(
          onSaved: onSaved,
          validator: validator,
          autovalidateMode: AutovalidateMode.always, // 검증 함수를 실시간으로 실행(?)해주는 듯.
          decoration: InputDecoration(
            filled: true,
            fillColor: Colors.grey[200],
          ),
        ),
        const SizedBox(height: 20,),
      ],
    );
  }
}

실제 화면에서 사용

final formKey = GlobalKey<FormState>();
final String id = '';
final String pw = '';

  renderButton() {
    return ElevatedButton(
      onPressed: () async {
        if (formKey.currentState!.validate()) { // 검증 통과 시 true가 반환되는 듯.
          debugPrint('통과됨');
          formKey.currentState!.save(); // 변수에 저장이 된다.
        }
      },
      child: const Text(
        '테스트',
        style: TextStyle(color: Colors.black, fontSize: 16),
      ),
    );
  }
// ...
Form(
  key: formKey,
  child: Column(
    children: [
      RenderTextField(
        label: '아이디',
        onSaved: (value) {
       	  setState(() {
              this.id = value;
          }
        },
        validator: (value) {
          if(value.length < 1) return '반드시 입력해야 합니다';
          if(value.length < 4) return '4글자 이상 입력해야 합니다';
          return null;
        },
      ),
      RenderTextField(
        label: '비밀번호',
        onSaved: (value) {
           setState(() {
              this.id = value;
          }
        },
        validator: (value) {
          if(value.length < 1) return '반드시 입력해야 합니다';
          if(value.length < 8) return '8글자 이상 입력해야 합니다';
          return null;
        },
      ),
      const SizedBox(
          height: 10,
      ),
      renderButton(),
    ],
  ),
),
// ...
profile
즐거워지고 싶다.

0개의 댓글