Flutter/UI

[Flutter] TextFormField

찌김이 2022. 9. 4. 06:00
728x90
반응형

Form 과 함께 많이 쓰이는 TextFormField 를 포스팅합니다.

TextFormField 의 기능은 너무 많으니 자주 쓰는 것들로 해서 기록용으로 포스팅하려고 합니다.

 

TextFormField()

 

글자 수 제한

  • maxLength 로 글자 수를 제한할 수 있습니다. 
  • maxLength 를 적용하면 우측 하단에 counterText 가 나타납니다.

 

TextFormField(
  maxLength: 6,
)

 

  • counterText 는 decoration 의 InputDecoration 을 이용하여 바꿔줄 수 있습니다.
  • counterStyle 로 꾸밀 수 있지만 counter 를 이용하여 임의로 만들 수 있습니다.
  • counter 가 적용되어 있다면 counterText 와 counterStyle 은 무시합니다.
TextFormField(
  maxLength: 6,
  decoration: const InputDecoration(
    
    counterText: 'counterText',
    counterStyle: TextStyle(),
    
    // custom
    counter: Text('counter')
  ),
)

 

 

  • 우측 하단 counterText 를 제거하고 싶다면 공백으로 두면 됩니다.

 

TextFormField(
  maxLength: 6,
  decoration: const InputDecoration(
    counterText: ''
  ),
)

 

 

 

키패드 설정

 

keyboardType

  • 텍스트 키패드, 숫자 키패드만 나타내고 싶을 때 keyboardType 으로 설정합니다.

 

TextFormField(
  keyboardType: TextInputType.number // TextInputType.text
)

 

 

textInputAction

  • 키패드의 액션 버튼 설정은 textInputAction 으로 합니다.
  • 액션 버튼을 클릭하면 onFieldSubmitted 이 호출되며, onFieldSubmitted 는 입력값을 반환합니다.
  • 자주 사용되는 값은 search, next, done 입니다.

 

TextFormField(
  
  // TextInputAction.search - 돋보기
  // TextInputAction.next - 다음
  // TextInputAction.done - 확인
  
  textInputAction: TextInputAction.search,
  onFieldSubmitted: (String value) { // TextFormField 입력값 반환
    print('value = $value');
  },
)

 

 

 

입력값 제한

  • 입력값을 필터링하기 위해 inputFormatters 를 사용합니다.

 

  • 숫자만 입력받고 싶을 때
TextFormField(
   inputFormatters: [
     FilteringTextInputFormatter.digitsOnly,
   ],
)

 

  • 정규표현식으로 제한하고 싶을 때 (해당 예시는 영문, 한글만 입력 받고 싶을 때입니다.)
TextFormField(
  inputFormatters: [
    FilteringTextInputFormatter(
      RegExp('[a-z A-Z ㄱ-ㅎ|가-힣|·|:]'),
      allow: true,
    )
  ],
)

 

  • 화폐 단위로 표현하고 싶을 때 - ex) 1,234,567
TextFormField(
  keyboardType: TextInputType.number,
  inputFormatters: [
    CurrencyTextInputFormatter(
      locale: 'ko',
      decimalDigits: 0,
      symbol: '',
    )
  ],
)

 

화폐 단위 구현은 직접 구현해도 되지만 저는 CurrencyTextInputFormatter 를 이용했습니다.

intl 과 같이 추가해주세요.

 

currency_text_input_formatter | Flutter Package

Currency Text Input Formatter for Flutter. Use it easy and simple for your flutter app.

pub.dev

 

pubspec.yaml

dependencies:
  intl: ^0.17.0
  currency_text_input_formatter: ^2.1.7

 

 

 

유효성 검사

  • 유효성 검사를 하기 위해서는 validator 와 Form 위젯이 필요합니다.

 

 

  • Form 사용을 위해서 GlobalKey<FormState>() 변수를 선언해주세요.
final _formKey = GlobalKey<FormState>();

 

  • TextFormField 를 Form 으로 감싸주고 key 를 넣어줍니다.
Form(
  key: _formKey,
  child: TextFormField(
    validator: (value) {
      if (value!.isEmpty) {
        return '1자 이상 입력해주세요.';
      }
    },
  ),
)

 

  • 예를 들어 클릭이벤트가 있는 위젯으로 formKey 를 validate 해주면 끝납니다.
  • formKey 를 save 해주면 Form 내부의 TextFormField 들의 onSaved 가 호출됩니다.
ElevatedButton(
  onPressed: () {
    final formKeyState = _formKey.currentState!;
    if (formKeyState.validate()) {
      formKeyState.save();
    }
  },
  child: const Text('확인'),
)

 

  • 아래에 뜨는 errorText 는 decoration 에서 InputDecoration의 errorBorder, errorStyle, focusedErrorBorder 을 이용하여 꾸밀 수 있습니다.
TextFormField(
  decoration: const InputDecoration(
    errorBorder: UnderlineInputBorder(
      borderSide: BorderSide(
        color: Colors.black,
        width: 2,
        strokeAlign: StrokeAlign.outside
      )
    ),
    errorStyle: TextStyle(),
    focusedErrorBorder: UnderlineInputBorder(
      borderSide: BorderSide(
         color: Colors.orange,
         width: 2,
      )
    )
  )
  .
  .
  .
)

 

 

onSaved

  • formKey 를 save 하면서 onSaved 가 호출됩니다.
  • 보통 여기서 선언한 변수를 setState 해주고 사용합니다.
String _textFormFieldValue = '';
.
.
.

TextFormField(
  validator: (value) {
    if (value!.isEmpty) {
      return '1자 이상 입력해주세요.';
    }
  },
  onSaved: (value) {
    setState(() {
      _textFormFieldValue = value!;
    });
  },

 

 

 

기타

 

TextFormField(
  decoration: const InputDecoration(
    border: OutlineInputBorder(),
    
    // enabledBorder 가 들어간다면 border 는 무시됩니다.
    enabledBorder: OutlineInputBorder(
       borderSide: BorderSide(
       color: Colors.green,
    ))
  ),
)

 

 

TextFormField(
   decoration: const InputDecoration(
      border: OutlineInputBorder(),
      focusedBorder: OutlineInputBorder(
         borderSide: BorderSide(
            color: Colors.orange,
         ),
      ),
   ),
)

 

 

TextFormField(
  decoration: const InputDecoration(
    border: OutlineInputBorder(),
  ),
  maxLines: 6,
)

 

 

TextFormField(
  // left, right, start, end, justify, center,
  textAlign: TextAlign.end,
)

 

 

TextFormField(
  style: const TextStyle(
    color: Colors.orange,
    fontSize: 20
  ),
)

 

 

TextFormField(
  cursorColor: Colors.orange,
  cursorWidth: 3,
  
  // 커서 노출 여부
  showCursor: true
)

 

728x90
반응형